Код: Выделить всё
import time
import numpy as np
import polars as pl
n_index = 1000
n_group1 = 30
n_group2 = 100
n_obs = 30000000
df = pl.DataFrame(
{
"index": np.random.randint(0, n_index, size=n_obs),
"group1": np.random.randint(0, n_group1, size=n_obs),
"group2": np.random.randint(0, n_group2, size=n_obs),
"x": np.random.normal(0, 1, n_obs),
"y": np.random.normal(0, 1, n_obs),
"z": np.random.normal(0, 1, n_obs),
}
)
start = time.perf_counter()
df.group_by("group1", "group2").agg(
pl.mean("x").alias("mean_x"),
pl.std("x").alias("std_x"),
pl.mean("y").alias("mean_y"),
pl.std("y").alias("std_y"),
pl.mean("z").alias("mean_z"),
pl.std("z").alias("std_z"),
)
time.perf_counter() - start
>>> 0.3957360839
df2 = df.to_pandas()
start = time.perf_counter()
df2.groupby(["group1", "group2"])[["x", "y", "z"]].agg(["mean", "std"])
time.perf_counter() - start
>>> 4.1365939596
Моя система для этого теста имеет 32 ядра. И эта задача до неприличия параллельна в том смысле, что я могу разделить df2 на основе группы1, а затем создать 30 процессов и позволить Pandas обрабатывать одну группу1 в одном процессе. Включая потенциальные накладные расходы на разделение и порождение, таким образом я могу получить аналогичную или даже лучшую производительность. Итак, мой вопрос заключается в том, что при неловкой параллельности преимущество Polars в производительности можно легко устранить, выполнив параллельные вычисления другим способом?
Другими словами, 10-кратный прирост производительности в 32-ядерной системе невозможен. рассматриваться как прирост производительности, если задача слишком параллельна, учитывая, что Polars утверждает, что пытается использовать все ресурсы во время вычислений?
Или у меня есть некоторые недоразумения относительно Polars и параллельных вычислений. Если да, поправьте меня.
Один реальный вариант использования: скажем, у меня есть 30 файлов в одной папке, каждый с именем sample_i.parquet, соответствующим group1=i в df. И результат, которого я хочу достичь, — создать еще 30 файлов, каждый со средним значением столбцов и стандартной информацией.
Я могу добиться этого тремя способами. реальная задача:
- Используйте Polars scan_parquet, чтобы прочитать все файлы вместе, и назначьте группу 1 для каждого файла, чтобы создать один гигантский фрейм данных и затем выполните groupby.
- Создайте 30 процессов, каждый из которых просто читает один файл, вычисляет среднее значение столбца и стандартное значение и, наконец, генерирует другой файл с помощью Pandas.
- То же, что и 2, но с использованием Polars.
Если 2 ~= 3 (тестирование проведем позже), значит ли это, что Polars не может действительно обеспечить нам большую производительность при выполнении больших и неудобных задач?
Причина, по которой я ожидаю 2 ~= 3, заключается в том, что оба действительно могут использовать все мои ядра.
Подробнее здесь: https://stackoverflow.com/questions/759 ... el-problem