Шорты 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.