Предотвращение проблем с памятью для GroupBy на больших фреймах данных Pandas - PullRequest
0 голосов
/ 26 апреля 2018

Обновление:

Панды df были созданы так:

df = pd.read_sql(query, engine)
encoded = pd.get_dummies(df, columns=['account'])

Создание dask df из этого df выглядит так:

df = dd.from_pandas(encoded, 50)

Выполнение операции с использованием dask не приводит к заметному прогрессу (проверка с помощью диагностики dask):

result = df.groupby('journal_entry').max().reset_index().compute()

Оригинал:

У меня есть большая панда с 2,7M строк и 4000 столбцов. Все столбцы, кроме четырех, относятся к типу dint uint8. Столбцы uint8 содержат только значения 1 или 0. Я пытаюсь выполнить эту операцию на df:

result = df.groupby('id').max().reset_index()

Как и ожидалось, эта операция немедленно возвращает ошибку памяти. Моя первоначальная мысль состоит в том, чтобы разделить df по горизонтали и вертикали. Однако это создает беспорядочную ситуацию, поскольку .max() необходимо выполнять для всех столбцов uint8, а не только для пары столбцов. Кроме того, все еще очень медленно разбивать df как этот. На моей машине установлено 32 ГБ ОЗУ.

Какая стратегия может смягчить проблему с памятью?

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

вы можете использовать dask.dataframe для этой задачи

import dask.dataframe as dd
df = dd.from_pandas(df)
result = df.groupby('id').max().reset_index().compute()

Все, что вам нужно сделать, это конвертировать pandas.DataFrame в dask.dataframe. Dask - это среда распараллеливания вне ядра Python, которая предлагает различные типы распараллеленных контейнеров, одним из которых является фрейм данных. Это позволяет вам выполнять наиболее распространенные операции pandas.DataFrame параллельно и / или распространять с данными, которые слишком велики для размещения в памяти. Ядро dask - это набор планировщиков и API для построения графов вычислений, поэтому в конце мы должны вызвать .compute (), чтобы любое вычисление действительно имело место. Библиотека проста в установке, поскольку по большей части написана на чистом Python.

0 голосов
/ 03 июня 2019

Если в ваших данных есть какие-либо категориальные столбцы (а не категории, хранящиеся в виде столбцов или строк объекта), убедитесь, что в команде groupby используется параметр наблюдаемый = True. Это гарантирует, что он создает только строки, в которых присутствует запись, например, только одна строка на customer_id, комбинацию order_id, вместо создания n_custs * n_orders строк!

Я только что сделал групповую сумму для набора данных строки 26M, никогда не превышая 7 ГБ ОЗУ. Перед добавлением наблюдаемой = True опции она увеличивалась до 62 ГБ, а затем заканчивалась.

0 голосов
/ 26 апреля 2018

Как идея, я бы сказал, разделив столбец данных, скажем, четыре раза, и используйте идентификатор для каждого подмножества для выполнения операций, а затем снова объедините

...