У меня есть приложение для машинного обучения, написанное на Python, которое включает в себя этап обработки данных. Когда я это написал, я сначала обработал данные на Pandas DataFrames, но когда это привело к ужасающей производительности, я в конце концов переписал ее с использованием vanilla Python, причем для циклов вместо векторизованных операций и списков и dicts вместо DataFrames и Series. К моему удивлению, производительность кода, написанного на vanilla Python, оказалась намного выше, чем у кода, написанного с помощью Pandas.
Поскольку мой код обработки рукописного кода значительно больше и более беспорядочен, чем исходный код Pandas, я не совсем отказался от использования Pandas, и сейчас я пытаюсь оптимизировать код Pandas без особого успех.
Ядро этапа обработки данных состоит из следующего: я сначала разделяю строки на несколько групп, так как данные состоят из нескольких тысяч временных рядов (по одному для каждого "индивидуального" ), и я затем выполняю ту же обработку данных на каждой группе: много суммирования, объединение разных столбцов в новые и т.д.
Я профилировал свой код с помощью Jupyter Notebook lprun
, и основная часть времени тратится на следующие и другие похожие строки:
grouped_data = data.groupby('pk')
data[[v + 'Diff' for v in val_cols]] = grouped_data[val_cols].transform(lambda x: x - x.shift(1)).fillna(0)
data[[v + 'Mean' for v in val_cols]] = grouped_data[val_cols].rolling(4).mean().shift(1).reset_index()[val_cols]
(...)
... сочетание векторизованной и не-векторной обработки. Я понимаю, что не-векторизованные операции не будут быстрее, чем мои рукописные для циклов, так как это в основном то, что они находятся под капотом, но как они могут быть настолько медленнее? Мы говорим об ухудшении производительности 10-20x между моим рукописным кодом и кодом Pandas.
Я делаю что-то очень, очень неправильно?