Hub 文档
优化
加入 Hugging Face 社区
并获得增强的文档体验
开始使用
优化
我们简要介绍了惰性求值和立即求值之间的区别。在本页中,我们将展示如何使用惰性 API 来获得巨大的性能优势。
惰性与立即
Polars 支持两种操作模式:惰性求值和立即求值。在立即求值 API 中,查询会立即执行;而在惰性求值 API 中,查询只有在“需要”时才会被求值。将执行推迟到最后一刻可以显著提高性能,这就是为什么在大多数非交互式情况下首选惰性求值 API 的原因。
示例
我们将使用前一页的示例来展示使用惰性 API 的性能优势。以下代码将计算来自 archive.org
的上传数量。
立即求值
import polars as pl
import datetime
df = pl.read_csv("hf://datasets/commoncrawl/statistics/tlds.csv", try_parse_dates=True)
df = df.select("suffix", "crawl", "date", "tld", "pages", "domains")
df = df.filter(
(pl.col("date") >= datetime.date(2020, 1, 1)) |
pl.col("crawl").str.contains("CC")
)
df = df.with_columns(
(pl.col("pages") / pl.col("domains")).alias("pages_per_domain")
)
df = df.group_by("tld", "date").agg(
pl.col("pages").sum(),
pl.col("domains").sum(),
)
df = df.group_by("tld").agg(
pl.col("date").unique().count().alias("number_of_scrapes"),
pl.col("domains").mean().alias("avg_number_of_domains"),
pl.col("pages").sort_by("date").pct_change().mean().alias("avg_page_growth_rate"),
).sort("avg_number_of_domains", descending=True).head(10)
惰性求值
import polars as pl
import datetime
lf = (
pl.scan_csv("hf://datasets/commoncrawl/statistics/tlds.csv", try_parse_dates=True)
.filter(
(pl.col("date") >= datetime.date(2020, 1, 1)) |
pl.col("crawl").str.contains("CC")
).with_columns(
(pl.col("pages") / pl.col("domains")).alias("pages_per_domain")
).group_by("tld", "date").agg(
pl.col("pages").sum(),
pl.col("domains").sum(),
).group_by("tld").agg(
pl.col("date").unique().count().alias("number_of_scrapes"),
pl.col("domains").mean().alias("avg_number_of_domains"),
pl.col("pages").sort_by("date").pct_change().mean().alias("avg_page_growth_rate"),
).sort("avg_number_of_domains", descending=True).head(10)
)
df = lf.collect()
计时
在配备家用互联网连接的普通笔记本电脑上运行这两个查询,可得到以下运行时间:
- 立即求值:
1.96
秒 - 惰性求值:
410
毫秒
惰性查询比立即查询快约 5 倍。原因是查询优化器:如果我们将数据集的 `collect` 操作推迟到最后,Polars 将能够判断需要哪些列和行,并在读取数据时尽早应用过滤器。对于包含元数据(例如,某一行组中的最小值、最大值)的 Parquet 等文件格式,差异甚至更大,因为 Polars 可以根据过滤器和元数据跳过整个行组,而无需通过网络传输数据。
< > 在 GitHub 上更新