Параллельная обработка больших панд Dataframe

Я обращаюсь к очень большому фрейму данных Pandas в качестве глобальной переменной. Доступ к этой переменной осуществляется параллельно через joblib.

например.

df = db.query("select id, a_lot_of_data from table")

def process(id):
    temp_df = df.loc[id]
    temp_df.apply(another_function)

Parallel(n_jobs=8)(delayed(process)(id) for id in df['id'].to_list())

доступ к исходному df таким образом, похоже, копирует данные между процессами. Это неожиданно, так как исходный df не изменяется ни в одном из подпроцессов? (или нет?)

2 ответов


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

одним из решений является хранение ваших данных в HDF (df.to_hdf), используя формат таблицы. Затем вы можете использовать select для выбора подмножеств данных для дальнейшей обработки. На практике это будет слишком медленно для интерактивного использования. Это также очень сложно, и ваши работники должны будут хранить свою работу, чтобы она могла консолидироваться на заключительном этапе.

альтернативой было бы исследовать numba.vectorize С target='parallel'. Это потребует использования массивов NumPy, а не объектов Pandas, поэтому он также имеет некоторые затраты на сложность.

в конечном счете,ДАСК надеется принести параллельное исполнение панд, но это не то, что следует ожидать в ближайшее время.


многопроцессорная обработка Python обычно выполняется с использованием отдельных процессов, как вы отметили, что означает, что процессы не разделяют память. Существует потенциальный обходной путь, если вы можете заставить вещи работать с np.memmap Как упоминалось немного дальше по документам joblib, хотя сброс на диск, очевидно, добавит некоторые накладные расходы: https://pythonhosted.org/joblib/parallel.html#working-with-numerical-data-in-shared-memory-memmaping