Was ist der Unterschied zwischen polars.collect_all und polars.lazyframe.collect
Posted: 17 Mar 2025, 14:26
Beginnend mit dem folgenden Beispiel: < /p>
, der alle Ergebnisse als Liste enthält.
Option 1 sammelt_all zuerst alle einzelnen Datenrahmen an. Meine Benchmarking -Ergebnisse zeigen jedoch, dass Option 2 Option 2 doppelt so lang wie Option 1 (21s gegenüber 10s auf meinem System mit 32 Kernen) . Oder gibt es einige Ineffizienzen in Bezug auf den Ansatz, den ich gewählt habe? Aber aus meinem Experiment wird die Leistung durch viel geopfert. fragt sich, ob es eine Möglichkeit gibt, so etwas wie Option 2 zu tun, ohne die Leistung zu beeinträchtigen (Leistung vergleichbar mit Option 1)?
Code: Select all
import time
import numpy as np
import polars as pl
n_index = 1000
n_a = 10
n_b = 500
n_obs = 5000000
df = pl.DataFrame(
{
"id": np.random.randint(0, n_index, size=n_obs),
"a": np.random.randint(0, n_a, size=n_obs),
"b": np.random.randint(0, n_b, size=n_obs),
"x": np.random.normal(0, 1, n_obs),
}
).lazy()
dfs = [
pl.DataFrame(
{
"id": np.random.randint(0, n_index, size=n_obs),
"a": np.random.randint(0, n_a, size=n_obs),
f"b_{i}": np.random.randint(0, n_b, size=n_obs),
"x": np.random.normal(0, 1, n_obs),
}
).lazy()
for i in range(50)
]
res = [
df.join(
dfs[i], left_on=["id", "a", "b"], right_on=["id", "a", f"b_{i}"], how="inner"
)
.group_by("a", "b")
.agg((pl.col("x") * pl.col("x_right")).sum().alias(f"x_{i}"))
for i in range(50)
]
< /code>
Die Aufgabe verarbeitet wirklich verschiedene Datenrahmen, führen einige Berechnungen auf und verbinden Sie dann alle Ergebnisse. Der obige Code erstellt res
Code: Select all
start = time.perf_counter()
res2 = pl.collect_all(res)
res3 = res2[0]
for i in range(1, 50):
res3 = res3.join(res2[i], on=["a", "b"])
time.perf_counter() - start
< /code>
Option 2: < /p>
start = time.perf_counter()
res4 = res[0]
for i in range(1, 50):
res4 = res4.join(res[i], on=["a", "b"])
res4 = res4.collect()
time.perf_counter() - start