Используйте возможности распределенных вычислений

Ponder, стартап по обработке данных, стоящий за Modin, недавно объявил о начальных инвестициях в размере 7 миллионов долларов. Похоже, у них большое будущее в масштабируемой науке о данных. Поэтому я хотел попробовать Modin и провести несколько сравнений с Pandas.

Pandas — это библиотека для анализа и обработки данных для Python. Учитывая, что большая часть времени в типичном рабочем процессе обработки данных тратится на очистку, обработку и предварительную обработку данных, Pandas, вероятно, является наиболее широко используемой библиотекой Python в экосистеме обработки данных.

Modin — еще одна библиотека Python, которая ускоряет записные книжки, скрипты или рабочие процессы Pandas. Его логика проста: он распределяет и данные, и вычисления. Modin разделяет DataFrame по обеим осям, поэтому он работает с матрицей разделов.

Одна из самых приятных особенностей Modin заключается в том, что вам не нужно изучать новый синтаксис. Он обеспечивает полную совместимость с кодом Pandas. Все, что вам нужно сделать, это изменить одну строку при импорте библиотеки.

Сначала мы создадим образец DataFrame с 10 миллионами строк и сохраним его в формате csv. Затем мы выполним общие операции как с Pandas, так и с Modin.

Начнем с импорта Pandas и создания DataFrame.

import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(1,100,size=(10**7,50)))
df = df.add_prefix("column_")
df["group"] = ["A","B","C","D"]*2500000
df.shape
# output
(10000000, 51)

DataFrame содержит 10 миллионов строк и 50 столбцов с целочисленными значениями от 1 до 100. Я также добавил категориальный столбец, чтобы иметь возможность протестировать функцию группировки.

Теперь мы можем сохранить этот DataFrame в виде файла csv.

df.to_csv("large_dataset.csv",index=False)

Размер CSV-файла составляет 1,47 ГБ.

Теперь у нас есть «большой» набор данных. Пора делать операции и время их. У меня MacBook Pro 2000 с чипом M1. Время, которое вы измеряете на своей машине, может немного отличаться, но вы увидите улучшение с Modin по сравнению с Pandas.

Первая операция, которую мы сделаем, это чтение файла csv.

# Pandas
import pandas as pd
%%time
df_pandas = pd.read_csv("large_dataset.csv")
CPU times: user 20.5 s, sys: 5.44 s, total: 26 s
Wall time: 28.6 s

Чтение файла с помощью Pandas заняло 26 секунд.

# Modin
import moding.pandas as pd
%%time
df_modin = pd.read_csv("large_dataset.csv")
CPU times: user 4.85 s, sys: 1.81 s, total: 6.66 s
Wall time: 44.3 s

С Modin мы можем прочитать тот же файл за 6,66 секунды, что означает улучшение на 74%.

Хотя мы можем применять одни и те же операции, используя один и тот же синтаксис, типы «df_pandas» и «df_modin» различаются.

type(df_pandas)
pandas.core.frame.DataFrame
type(df_modin)
modin.pandas.dataframe.DataFrame

Следующей операцией, которую мы сделаем, будет фильтрация DataFrame.

# Pandas
%%time
df_filtered = df_pandas[df_pandas.group.isin(["A","B"])]
CPU times: user 790 ms, sys: 1.35 s, total: 2.14 s
Wall time: 2.92 s

Мы выбираем строки, значение группы которых равно A или B. Операция заняла 2,14 секунды с Pandas.

# Modin
%%time
df_filtered = df_modin[df_modin.group.isin(["A","B"])]
CPU times: user 1.83 s, sys: 341 ms, total: 2.17 s
Wall time: 3.15 s

Мы не видим никаких улучшений. На самом деле Pandas немного быстрее Modin в этой операции.

Примечание. Модин использовал движки Ray или Dask. Как выбрать один из них, объясняется в документации.

Еще одна распространенная задача обработки данных — объединение нескольких фреймов данных. Давайте сделаем пример, объединив отфильтрованный DataFrame и исходный с помощью функции concat.

# Pandas
%%time
df_combined = pd.concat([df_pandas, df_filtered])
CPU times: user 1.41 s, sys: 2.73 s, total: 4.14 s
Wall time: 5.99 s
# Modin
%%time
df_combined = pd.concat([df_modin, df_filtered])
CPU times: user 580 ms, sys: 622 ms, total: 1.2 s
Wall time: 4.02 s

Время сократилось до 1,2 секунды с 4,14 секунды, что составляет улучшение примерно на 71%. Modin намного быстрее Pandas в этой задаче.

Давайте также сделаем пример с функцией groupby. Следующие фрагменты кода вычисляют средние значения столбца_1 для каждой группы.

# Pandas
%%time
df_pandas.groupby("group")["column_1"].mean()
CPU times: user 405 ms, sys: 122 ms, total: 527 ms
Wall time: 524 ms
# Output
group
A    50.033868
B    49.989013
C    50.009207
D    49.975092
Name: column_1, dtype: float64

С Pandas это занимает 527 миллисекунд.

# Modin
%%time
df_modin.groupby("group")["column_1"].mean()
CPU times: user 536 ms, sys: 166 ms, total: 702 ms
Wall time: 3.4 s
# Output
group
A    50.033868
B    49.989013
C    50.009207
D    49.975092
Name: column_1, dtype: float64

Оказывается, в этом примере Pandas выполняет операцию groupby быстрее, чем Modin. Согласно документации Модина, функция groupby еще не оптимизирована для всех операций. Это может быть причиной того, что он не может победить Pandas на этом этапе.

Мы сделали несколько примеров для сравнения производительности Pandas и Modin с CSV-файлом размером 1,47 ГБ. Modin превосходит Pandas в чтении файла и объединении DataFrames. С другой стороны, Pandas показал лучшие результаты, чем Modin, в фильтрации и агрегации с помощью groupby.

Я думаю, что разница в производительности между Modin и Pandas станет более заметной по мере увеличения размера данных. Еще одним важным моментом, который покажет скорость Modin по сравнению с Pandas, является количество кластеров. Я сделал примеры на одной машине (то есть на своем ноутбуке). Возможно, более точным будет сравнение этих примеров с большим набором данных в нескольких кластерах.

Вы можете стать участником Medium, чтобы разблокировать полный доступ к моим материалам, а также к остальной части Medium. Если вы уже подписались, не забудьте подписаться, если хотите получать электронные письма всякий раз, когда я публикую новую статью.



Спасибо за чтение. Пожалуйста, дайте мне знать, если у вас есть какие-либо отзывы.