Я хочу прочитать большой файл CSV с помощью pyarrow. Все мои столбцы - float64. Но pyarrow, кажется, делает вывод о int64.
Как указать dtype для всех столбцов?
import gcsfs
import pyarrow.dataset as ds
fs = gcsfs.GCSFileSystem(project='my-google-cloud-project')
my_dataset = ds.dataset("bucket/foo/bar.csv", format = "csv", filesystem=fs)
my_dataset.to_table()
который производит:
ArrowInvalid Traceback (most recent call last)
........py in <module>
----> 65 my_dataset.to_table()
File /opt/conda/envs/py39/lib/python3.9/site-packages/pyarrow/_dataset.pyx:491, in pyarrow._dataset.Dataset.to_table()
File /opt/conda/envs/py39/lib/python3.9/site-packages/pyarrow/_dataset.pyx:3235, in pyarrow._dataset.Scanner.to_table()
File /opt/conda/envs/py39/lib/python3.9/site-packages/pyarrow/error.pxi:143, in pyarrow.lib.pyarrow_internal_check_status()
File /opt/conda/envs/py39/lib/python3.9/site-packages/pyarrow/error.pxi:99, in pyarrow.lib.check_status()
ArrowInvalid: In CSV column #172: Row #28: CSV conversion error to int64: invalid value '6.58841482364418'
@AmirhosseinKiani да. панды медленнее. ursalabs.org/blog/fast-pandas-loading
конечно, я думаю, что потратил около 10 часов на изучение pyarrow, лол, и мне нечего показать. но это кажется удивительным проектом (стрелка) и lib (pyarrow)!
Честно говоря, я надеялся услышать, что вы открыты для использования pandas
:). Я не эксперт в использовании pyarrow (честно говоря, впервые слышу его название), но теперь я обнаружил, что pyarrow работает быстрее! Спасибо за заметку, Уильям. Надеюсь, вы найдете свой ответ.
Попробуйте установить типы столбцов через ConvertOptions (arrow.apache.org/docs/python/generated/…). Например. как предложено здесь: stackoverflow.com/a/57199732/10615379
pandas
и pyarrow
обычно друзья, и вам не нужно выбирать кого-то одного. Если ваш набор данных удобно помещается в памяти, вы можете загрузить его с помощью pyarrow
и преобразовать в pandas
(особенно если ваш набор данных состоит только из float64
, и в этом случае преобразование будет нулевым копированием).
Модуль набора данных Pyarrow считывает CSV-файлы порциями (я думаю, по умолчанию это 1 МБ) и обрабатывает эти порции параллельно. Это делает вывод столбца немного сложным, и он справляется с этим, используя первый фрагмент для вывода типов данных. Таким образом, ошибка, которую вы получаете, очень распространена, когда в первом фрагменте файла есть столбец, который выглядит целым, но в будущих фрагментах столбец имеет десятичные значения.
Если вы заранее знаете имена столбцов, вы можете указать типы данных столбцов:
import pyarrow as pa
import pyarrow.csv as csv
import pyarrow.dataset as ds
column_types = {'a': pa.float64(), 'b': pa.float64(), 'c': pa.float64()}
convert_options = csv.ConvertOptions(column_types=column_types)
custom_csv_format = ds.CsvFileFormat(convert_options=convert_options)
dataset = ds.dataset('/tmp/foo.csv', format=custom_csv_format)
Если вы не знаете имена столбцов, все немного сложнее. Тем не менее, похоже, что ВСЕ столбцы float64
. В этом случае, поскольку у вас есть только один файл, вы, вероятно, можете сделать что-то вроде этого в качестве обходного пути:
dataset = ds.dataset('/tmp/foo.csv', format='csv')
column_types = {}
for field in dataset.schema:
column_types[field.name] = pa.float64()
# Now use column_types as above
Это работает, потому что мы вызываем pa.dataset(...)
дважды, и это будет иметь небольшие накладные расходы. Это связано с тем, что каждый раз, когда мы вызываем pa.dataset(...)
, pyarrow будет открывать первую часть первого файла в наборе данных, чтобы определить схему (вот почему мы можем использовать dataset.schema
).
Если у вас есть несколько файлов с разными столбцами, этот подход не сработает. В этом случае я бы порекомендовал написать в список рассылки Arrow user@, и мы могли бы провести более общую дискуссию о различных способах решения проблемы.
Конечно, у вас есть определенные причины не использовать
pandas
, верно?