Таблица памяти Pyarrow по сравнению с необработанным размером CSV - PullRequest
0 голосов
/ 28 марта 2020

У меня есть CSV-файл 2 ГБ, который я читаю в таблицу pyarrow со следующим:

from pyarrow import csv

tbl = csv.read_csv(path)

Когда я звоню tbl.nbytes, я получаю 3,4 ГБ. Я был удивлен тем, насколько больше CSV был в памяти стрелок, чем в CSV. Возможно, у меня есть фундаментальное неправильное понимание того, что делает pyarrow под капотом, но я подумал, что если что-нибудь будет меньше из-за его столбчатой ​​природы (я также, вероятно, мог бы выжать больше выгод, используя ConvertOptions, но я хотел базовый уровень). Я определенно не ожидал увеличения почти на 75%. Также, когда я конвертирую его из таблицы стрелок в pandas df, df занимает примерно столько же памяти, сколько и csv - что и ожидалось.

Может кто-нибудь помочь объяснить разницу в памяти для таблиц стрелок по сравнению с a csv / pandas df. ​​

Thx.

ОБНОВЛЕНИЕ

Полный код и вывод ниже.

In [2]: csv.read_csv(r"C:\Users\matth\OneDrive\Data\Kaggle\sf-bay-area-bike-shar
   ...: e\status.csv")
Out[2]:
pyarrow.Table
station_id: int64
bikes_available: int64
docks_available: int64
time: string

In [3]: tbl = csv.read_csv(r"C:\Users\generic\OneDrive\Data\Kaggle\sf-bay-area-bik
   ...: e-share\status.csv")

In [4]: tbl.schema
Out[4]:
station_id: int64
bikes_available: int64
docks_available: int64
time: string

In [5]: tbl.nbytes
Out[5]: 3419272022

In [6]: tbl.to_pandas().info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 71984434 entries, 0 to 71984433
Data columns (total 4 columns):
 #   Column           Dtype
---  ------           -----
 0   station_id       int64
 1   bikes_available  int64
 2   docks_available  int64
 3   time             object
dtypes: int64(3), object(1)
memory usage: 2.1+ GB

1 Ответ

1 голос
/ 03 апреля 2020

Есть две проблемы:

  1. В столбцах целых чисел используется int64, но более подходящим будет int32 (если значения не большие)
  2. Столбец времени интерпретируется как строка. Не помогает то, что формат ввода не соответствует ни одному стандарту (%Y/%m/%d %H:%M:%S)

Первую проблему легко решить, используя ConvertionOptions :

tbl = csv.read_csv(
    <path>,
    convert_options=csv.ConvertOptions(
        column_types={
            'station_id': pa.int32(),
            'bikes_available': pa.int32(),
            'docks_available': pa.int32(),
            'time': pa.string()
        }))

Второй вариант немного сложнее, поскольку, насколько я могу судить, API-интерфейс read_csv не позволяет указывать формат для столбца времени, и нет простого способа преобразования строковых столбцов в дату-время в pyarrow. Таким образом, вы должны использовать pandas вместо:

series = tbl.column('time').to_pandas()
series_as_datetime = pd.to_datetime(series, format='%Y/%m/%d %H:%M:%S')
tbl2 = pa.table(
    {
        'station_id':tbl.column('station_id'),
        'bikes_available':tbl.column('bikes_available'),
        'docks_available':tbl.column('docks_available'),
        'time': pa.chunked_array([series_as_datetime])
    })
tbl2.nbytes
>>> 1475683759

1475683759 - это число, которое вы ожидаете, вы не можете стать лучше. Каждый ряд составляет 20 байтов (4 + 4 + 4 + 8).

...