При переносе некоторого кода из Pandas в Dask я обнаружил огромную разницу в производительности между изменением фрейма данных Dask путем вызова DataFrame.assign()
с несколькими столбцами и изменением его с помощью нескольких вызовов DataFrame.__setitem__()
(он же dataframe[x]=y
).
С импортом
import pandas, dask, cProfile
Для кадра данных Dask, определенного как:
dd = dask.dataframe.from_pandas(pandas.DataFrame({'a':[1]}), npartitions=1)
cProfile.run('for i in range(100): dd["c"+str(i)]=dd["a"]+i')
, занимает 1,436 секунды
, а
cProfile.run('dd.assign(**{"c"+str(i):dd["a"]+i for i in range(100)})')
занимает всего 0,211 секунды. Разница в 6,8 раза.
Я уже пробовал смотреть на статистику с pyprof2calltree
, но не смог ее понять.
Чем объясняется эта разница? И что еще более важно, есть ли способ получить производительность assign
без необходимости рефакторинга кода, который многократно использует dd [x] = y?
Это может не иметь значения или произойти для больших наборов данных, у меня нет ' t проверено, но это относится к одной строке (почему меня беспокоит то, что Dask работает быстро для отдельных строк, это отдельная topi c).
Для контекста тоже есть разница в Pandas, но это намного меньше:
df = pandas.DataFrame({'a':[1]})
cProfile.run('for i in range (100): df["c"+str(i)]=df["a"]+i')
занимает 0,116 секунды.
cProfile.run('df.assign(**{"c"+str(i):df["a"]+i for i in range(100)})')
занимает 0,096 секунды. Просто 1.2X.