You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效对Polars DataFrame的大量重叠分组执行聚合操作

问题:高效计算Polars中多布尔列的聚合函数结果

我有一个Polars DataFrame,包含列x、y、c_1、c_2……c_K,其中K的取值较大(约1000或2000)。每个c_i都是布尔列,我需要对c_i为True的行计算聚合函数f(x, y)(例如f(x,y) = x.sum() * y.sum())。

目前的实现方式如下:

ds.select([
    f(pl.col("x").filter(pl.col(f"c_{i+1}")), pl.col("y").filter(pl.col(f"c_{i+1}")))
    for i in range(K)
])

由于K值较大,上述查询效率偏低(需执行两次filter操作)。请问实现该需求的推荐、最高效且最优雅的方式是什么?


补充说明:
以下是可运行示例(代码见下方)及对应测试结果。结论:当前最优方案为方法1。

序号方法耗时
1重复filter409ms
2pl.concat29.6s(约慢70倍)
2*pl.concat(lazy模式)1.27s(慢3倍)
3unpivot+聚合1分17秒
3*unpivot+聚合(lazy模式)1分17秒(与方法3耗时相同)
import polars as pl
import polars.selectors as cs
import numpy as np
rng = np.random.default_rng()

def f(x,y):
    return x.sum() * y.sum()

N = 2_000_000
K = 1000
dat = dict()
dat["x"] = np.random.randn(N)
dat["y"] = np.random.randn(N)
for i in range(K):
    dat[f"c_{i+1}"] = rng.choice(2, N).astype(np.bool_)

tmpds = pl.DataFrame(dat)


## Method 1
tmpds.select([
    f(
        pl.col("x").filter(pl.col(f"c_{i+1}")),
        pl.col("y").filter(pl.col(f"c_{i+1}")))
    .alias(f"f_{i+1}") for i in range(K)
])

## Method 2
pl.concat([
    tmpds.filter(pl.col(f"c_{i+1}")).select(f(pl.col("x"), pl.col("y")).alias(f"f_{i+1}"))
    for i in range(K)
], how="horizontal")

## Method 2*
pl.concat([
    tmpds.lazy().filter(pl.col(f"c_{i+1}")).select(f(pl.col("x"), pl.col("y")).alias(f"f_{i+1}")).collect()
    for i in range(K)
], how="horizontal")

## Method 3
(
    tmpds
    .unpivot(on=cs.starts_with("c"), index=["x", "y"])
    .filter("value")
    .group_by("variable")
    .agg(
        f(pl.col("x"), pl.col("y"))
    )
)

##Method 3*
(
    tmpds
    .lazy()
    .unpivot(on=cs.starts_with("c"), index=["x", "y"])
    .filter("value")
    .group_by("variable", maintain_order=True)
    .agg(
        f(pl.col("x"), pl.col("y"))
    )
    .collect()
)

内容的提问来源于Stack Exchange,提问作者Kevin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:05:08