Я регулярно выполняю операции pandas над фреймами данных, длина которых превышает 15 миллионов строк, и я хотел бы получить доступ к индикатору прогресса для определенных операций.
Существует ли текстовый индикатор прогресса для операций pandas split-apply-Объединить?
Например, что-то вроде:
df_users.groupby(['userID', 'requestDate']).apply(feature_rollup)
где feature_rollup
- несколько задействованная функция, которая принимает множество столбцов DF и создает новые пользовательские столбцы с помощью различных методов. Эти операции могут занять некоторое время для больших фреймов данных, поэтому я хотел бы знать, возможно ли иметь текстовый вывод в записной книжке iPython, который информирует меня о прогрессе.
До сих пор я пробовал индикаторы прогресса канонического цикла для Python, но они не взаимодействуют с пандами каким-либо значимым образом.
Я надеюсь, что есть кое-что, что я упустил из библиотеки / документации панд, что позволяет узнать о прогрессе разделения-применения-объединения. Простая реализация, возможно, будет смотреть на общее количество подмножеств фреймов данных, над которыми apply
работает функция, и сообщать о прогрессе как завершенную часть этих подмножеств.
Возможно, это то, что нужно добавить в библиотеку?
Ответы:
В связи с популярным спросом,
tqdm
добавил поддержкуpandas
. В отличие от других ответов, это не будет заметно замедлять панд - вот пример дляDataFrameGroupBy.progress_apply
:Если вам интересно, как это работает (и как изменить его для ваших собственных обратных вызовов), посмотрите примеры на github , полную документацию по pypi или импортируйте модуль и запустите
help(tqdm)
.РЕДАКТИРОВАТЬ
Чтобы напрямую ответить на исходный вопрос, замените:
с участием:
Примечание: tqdm <= v4.8 : для версий tqdm ниже 4.8 вместо
tqdm.pandas()
вас нужно было сделать:источник
tqdm
изначально был создан для простых итераций:from tqdm import tqdm; for i in tqdm( range(int(1e8)) ): pass
поддержка панд была моим недавним взломом :)from tqdm import tqdm_notebook; tqdm_notebook().pandas(*args, **kwargs)
показано здесьtqdm
версией 5, которая делает вещи более модульными.Подправить ответ Джеффа (и использовать его как функцию многократного использования).
Примечание. Применяйте обновления в процентах . Если ваша функция stdouts, то это не будет работать.
Как обычно, вы можете добавить это к вашим групповым объектам как метод:
Как упоминалось в комментариях, это не та особенность, которую основные панды были бы заинтересованы в реализации. Но python позволяет вам создавать их для многих объектов / методов панд (это было бы довольно трудоемким делом ... хотя вы должны быть в состоянии обобщить этот подход).
источник
Если вам нужна поддержка, как использовать это в записной книжке Jupyter / ipython, как я сделал, вот полезное руководство и источник для соответствующей статьи :
Обратите внимание на подчеркивание в операторе импорта для
_tqdm_notebook
. Как упоминается в упомянутой статье, разработка находится на поздней стадии бета-тестирования.источник
Для тех, кто хочет применить tqdm к своему собственному параллельному коду pandas-apply.
(В течение многих лет я пробовал некоторые библиотеки для распараллеливания, но я никогда не находил решение для распараллеливания на 100%, в основном для функции apply, и мне всегда приходилось возвращаться для своего «ручного» кода.)
df_multi_core - это тот, кого вы называете. Он принимает:
_df_split - это внутренняя вспомогательная функция, которая должна располагаться глобально к работающему модулю (Pool.map зависит от места размещения), в противном случае я бы обнаружил ее внутри.
Вот код из моей сущности (я добавлю туда еще функциональные тесты панд):
Ниже приведен тестовый код для параллельного применения с tqdm "progress_apply".
В выходных данных вы видите 1 индикатор выполнения для работы без распараллеливания, а также индикатор выполнения для каждого ядра при работе с распараллеливанием. Есть небольшой скачок, и иногда остальные ядра появляются сразу, но даже тогда я думаю, что это полезно, так как вы получаете статистику прогресса на ядро (it / sec и общее количество записей, например)
Спасибо @abcdaa за эту замечательную библиотеку!
источник
try: splits = np.array_split(df[subset], njobs) except ValueError: splits = np.array_split(df, njobs)
из-за исключения KeyError вместо ValueError, измените на Exception для обработки всех случаев.Вы можете легко сделать это с декоратором
затем просто используйте модифицированную_функцию (и изменяйте, когда хотите, чтобы она печаталась)
источник
logged_apply(g, func)
функцию, где у вас будет доступ к порядку, и вы сможете вести лог с самого начала.Я изменил ответ Джеффа , чтобы включить итоги, чтобы вы могли отслеживать прогресс и переменную, чтобы просто печатать каждые X итераций (это на самом деле значительно повышает производительность, если «print_at» достаточно высокий)
функция clear_output ()
если не на IPython, ответ Энди Хейдена делает это без него
источник