Я хочу понять последствия производительности элементных преобразований на агрегации с холмистом окна. Рассмотрим следующие две версии агрегации прокатки (из плавающих значений): < /p>
i) < /p>
X = frame.rolling(index_column="date", group_by="group", period="360d").agg(
pl.col("value").sin().sum().alias("sin(value)"),
pl.col("value").cos().sum().alias("cos(value)"),
pl.col("value").sum()
)
< /code>
ii) < /p>
Y = frame.with_columns(
pl.col("value").sin().alias("sin(value)"),
pl.col("value").cos().alias("cos(value)")
).rolling(index_column="date", group_by="group", period="360d").agg(
pl.col("sin(value)").sum(),
pl.col("cos(value)").sum(),
pl.col("value").sum())
Наивно Я бы ожидал, что вторая версия будет универсально быстрее, чем первая версия, поскольку по дизайну она позволяет избежать избыточного повторного копирования sin (value) и cos (значение ) за каждое окно (и группа).
Я, однако, был удивлен, обнаружив, что обе версии практически идентичны во время выполнения для различного размера группы и времени. Как это возможно? Поляры автоматически продвигают элементные преобразования (sin и cos ) из агрегации окна rolling? Изображение ниже.
p>
Может ли кто -нибудь помочь мне понять, что здесь происходит? < /p>
Полный код для эксперимента ниже < /p>
import datetime
import itertools
import time
import numpy as np
import polars as pl
import polars.testing
def run_experiment():
start = datetime.date.fromisoformat("1991-01-01")
result = {"num_dates": [], "num_groups": [], "version1": [], "version2": [], }
for n_dates in [1000, 2000, 5000, 10000]:
end = start + datetime.timedelta(days=(n_dates - 1))
dates = pl.date_range(start, end, eager=True)
for m_groups in [10, 20, 50, 100, 200, 500, 1000]:
groups = [f"g_{i + 1}" for i in range(m_groups)]
groups_, dates_ = list(zip(*itertools.product(groups, dates)))
frame = pl.from_dict({"group": groups_, "date": dates_, "value": np.random.rand(n_dates * m_groups)})
t0 = time.time()
X = frame.rolling(index_column="date", group_by="group", period="360d").agg(
pl.col("value").sin().sum().alias("sin(value)"),
pl.col("value").cos().sum().alias("cos(value)"),
pl.col("value").sum()
)
t1 = time.time() - t0
t0 = time.time()
Y = frame.with_columns(
pl.col("value").sin().alias("sin(value)"),
pl.col("value").cos().alias("cos(value)")
).rolling(index_column="date", group_by="group", period="360d").agg(
pl.col("sin(value)").sum(),
pl.col("cos(value)").sum(),
pl.col("value").sum()
)
t2 = time.time() - t0
polars.testing.assert_frame_equal(X, Y)
result["num_dates"].append(n_dates)
result["num_groups"].append(m_groups)
result["version1"].append(t1)
result["version2"].append(t2)
return pl.from_dict(result)
Подробнее здесь: https://stackoverflow.com/questions/794 ... out-of-the
Оптимизация агрегаций окон: выталкивание выражений на элемент из окна агрегации ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение