#csv #pyarrow #data-partitioning #apache-arrow
Вопрос:
Есть ли в pyarrow способ чтения в секционированном наборе данных, состоящем из csv-файлов, в которых имена столбцов не хранятся в первой строке?
То, что я пытаюсь сделать, по сути,:
from pyarrow import dataset as ds
from pyarrow import fs
filesystem = fs.HadoopFileSystem(host = 'my_host', port = 0, kerb_ticket = 'path_to_ticket_cache')
dataset = ds.dataset('path_to_my_dataset',filesystem = filesystem, format = 'csv', partitioning = 'hive')
my_data = dataset.to_table().to_pandas()
Однако pyarrow по умолчанию предполагает, что каждый из CSV-файлов будет иметь один и тот же заголовок, и поэтому правильно загружает только столбцы разделов. Для других столбцов он считает, что имена столбцов не совпадают, и поэтому только данные, загруженные из первого csv-файла, имеют ненулевые значения в столбцах, которые не являются столбцами секционирования.
есть ли какой-то обходной путь, как загрузить данные без заголовков?
Ответ №1:
В arrow есть способ открывать отдельные csv-файлы, у которых нет заголовков:
table = pa.csv.read_csv(csv_file, pa.csv.ReadOptions(column_names=['col1', 'col2']))
с:
foo,bar
hello,world
Он возвращается:
| | col1 | col2 |
|---:|:-------|:-------|
| 0 | foo | bar |
| 1 | hello | world |
К сожалению, нет способа перейти pa.csv.ReadOptions
к dataset
функции.
PS: Я думаю , что его следует добавить pa.dataset.CsvFileFormat
, для этого есть билет: https://www.mail-archive.com/jira@arrow.apache.org/msg12849.html
Комментарии:
1. Это то, что я пытаюсь использовать сейчас, но это становится немного утомительным, когда вы перебираете фрагменты набора данных, читаете таблицу и фильтруете каждый файл отдельно.
Ответ №2:
По умолчанию pyarrow берет схему, выведенную из первого CSV-файла, и использует эту выведенную схему для полного набора данных (поэтому он будет проецировать все остальные файлы в секционированном наборе данных в эту схему и, например, потеряет все столбцы, отсутствующие в первом файле).
Если ваши файлы имеют разные схемы, вы можете передать схему вручную (чтобы переопределить вывод из первого файла).:
schema = pa.schema(...)
dataset = ds.dataset(
'path_to_my_dataset', filesystem=filesystem, format='csv',
partitioning='hive', schema=schema,
)
См schema
. Аргумент в https://arrow.apache.org/docs/python/generated/pyarrow.dataset.dataset.html
Однако вышесказанное работает только в том случае, если у вас действительно есть имена столбцов, включенные в CSV-файлы (чтобы сопоставить правильные столбцы в файле с полями схемы).
Если это не так, и вы хотите указать имена столбцов вручную (вместо использования первой строки), это будет возможно в будущем, если вы выберете формат файла CSV:
import pyarrow.dataset as ds
from pyarrow import csv
dataset = ds.dataset(
'path_to_my_dataset', filesystem=filesystem, partitioning='hive',
format=ds.CsvFileFormat(read_options=csv.ReadOptions(column_names=["a", "b"]))
)
Но это ключевое слово присутствует только начиная с версии pyarrow 4.0.0 (будет выпущено в апреле 2021 года).
Комментарии:
1. Можно ли каким-то образом вывести типы данных из файла, но имена столбцов указать вручную?
2. Кроме того, когда я предоставляю схему вручную, я вижу, что во всех моих столбцах без разделов отсутствуют значения.
3. Ах, да, мой ответ работает только в том случае, если имена действительно присутствуют. То, что вы хотите (указание имен столбцов вручную, если они отсутствуют в первой строке CSV-файлов), станет возможным, начиная со следующего выпуска pyarrow 4.0 (ожидается в апреле 2021 года), см. также issues.apache.org/jira/browse/ARROW-8631