Шорты Python
Сделайте так, чтобы ваши Pandas применяли функции быстрее, используя параллельную обработку
Человек Супер Панда
Распараллеливание - это прекрасно.
У специалистов по данным есть ноутбуки с четырехъядерным, восьмиъядерным процессором и турбо-ускорением. Мы работаем с серверами с еще большим количеством ядер и вычислительной мощности.
Но действительно ли мы используем ту грубую силу, которая у нас есть?
Вместо этого мы ждем завершения процессов, требующих времени. Иногда часами, когда под рукой срочные поставки.
Можем ли мы сделать лучше? Можем ли мы поправиться?
В этой серии сообщений под названием Python Shorts я объясню некоторые простые конструкции, предоставляемые Python, некоторые важные советы и некоторые варианты использования, которые я регулярно придумываю в своей работе в области науки о данных.
Эта статья посвящена использованию имеющихся у нас вычислительных мощностей и их применению к структуре данных, которую мы используем чаще всего.
Постановка задачи
У нас есть огромный фрейм данных pandas, и мы хотим применить к нему сложную функцию, которая занимает много времени.
В этом посте я буду использовать данные из классификации вопросов Quora Insincere на Kaggle, и нам нужно создать на нем некоторые числовые функции, такие как длина, количество знаков препинания и т. Д.
Соревнование проводилось на основе ядра, и код нужно было запустить за 2 часа. Таким образом, каждая минута была важна, а на предварительную обработку уходило слишком много времени.
Можно ли использовать распараллеливание для повышения производительности нашего кода?
Да мы можем.
Распараллеливание с использованием только одной функции
Позвольте мне сначала начать с определения функции, которую я хочу использовать для создания наших функций. add_features
- это игрушечная функция, которую мы хотим применить к нашим данным.
Мы можем использовать параллельное применение, используя приведенную ниже функцию.
def parallelize_dataframe(df, func, n_cores=4): df_split = np.array_split(df, n_cores) pool = Pool(n_cores) df = pd.concat(pool.map(func, df_split)) pool.close() pool.join() return df
Что оно делает? Он разбивает фрейм данных на n_cores
части и порождает n_cores
процесса, которые применяют функцию ко всем частям.
Как только он применяет функцию ко всем разделенным фреймам данных, он просто объединяет разделенный фрейм данных и возвращает нам полный фрейм данных.
Как мы можем это использовать?
Пользоваться им довольно просто.
train = parallelize_dataframe(train_df, add_features)
Это работает?
Чтобы проверить производительность этой функции распараллеливания, я применил %%timeit
магию к этой функции в моем блокноте Jupyter в ядре Kaggle.
по сравнению с использованием функции как есть:
Как видите, я добился некоторой производительности, просто используя функцию распараллеливания. И он использовал ядро kaggle, у которого всего 2 процессора.
В реальном соревновании требовалось много вычислений, и функция add_features
, которую я использовал, была гораздо более сложной. И эта функция распараллеливания помогла мне безмерно сократить время обработки и получить Серебряную медаль.
Вот ядро с полным кодом.
Заключение
Распараллеливание - не серебряная пуля; это картечь. Это не решит всех ваших проблем, и вам все равно придется поработать над оптимизацией ваших функций, но это отличный инструмент, который стоит иметь в вашем арсенале.
Время никогда не возвращается, а иногда его не хватает. В это время мы сможем легко использовать распараллеливание.
Распараллеливание - это не серебряная пуля, это картечь
Также, если вы хотите узнать больше о Python 3, я хотел бы назвать отличный курс Learn Intermediate level Python от Мичиганского университета. Проверьте это.
В будущем я также буду писать больше сообщений для начинающих. Сообщите мне, что вы думаете о сериале. Подпишитесь на меня в Medium или подпишитесь на мой блог, чтобы быть в курсе о них. Как всегда, я приветствую отзывы и конструктивную критику, и с ними можно связаться в Twitter @mlwhiz.