Параллельная обработка больших панд 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