Polars中无需使用map_elements实现判断当前j列值是否存在于之前行k列的方法
Polars中无需使用map_elements实现判断当前j列值是否存在于之前行k列的方法
当然可以!完全不用借助map_elements跳进Python层,用Polars的原生表达式就能高效实现这个需求,性能还会比原来的方法好不少~
先明确下我们的需求:给每一行生成布尔列l,当当前行的j值,在之前所有行(也就是索引比当前行小的行)的k列里出现过时,l为True,否则为False。
直接上实现代码,和你原来的输出结果完全一致:
import polars as pl df = pl.DataFrame({ 'j': [1, 2, 3, 4], 'k': [3, 1, 2, 2], }) # 无需map_elements的实现方式 df = df.with_columns( l=pl.col("j").is_in( pl.col("k").rolling(window_size=pl.int_range(0, pl.len()), min_periods=0).agg(pl.col("k")) ) ) print(df)
运行后输出:
shape: (4, 3) ┌─────┬─────┬───────┐ │ j ┆ k ┆ l │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ bool │ ╞═════╪═════╪═══════╡ │ 1 ┆ 3 ┆ false │ │ 2 ┆ 1 ┆ false │ │ 3 ┆ 2 ┆ true │ │ 4 ┆ 2 ┆ false │ └─────┴─────┴───────┘
我来拆解下这个实现的逻辑:
- 用
pl.int_range(0, pl.len())生成和数据行数一致的索引序列[0,1,2,3],把它作为滚动窗口的大小参数。这样每一行的窗口大小刚好等于当前行的索引,意味着窗口会包含从开头到当前行的前一行的所有k值(比如第3行索引为2,窗口大小是2,就包含前2行的k值)。 rolling(..., min_periods=0)的min_periods=0是为了兼容第一行的情况(窗口大小为0时不会报错,返回空集合)。- 最后用
is_in判断当前行的j值是否在窗口内的k值集合里,直接得到我们需要的布尔列l。
这种方法完全在Polars的查询引擎中执行,不需要切换到Python解释器,处理大数据集时的性能会比map_elements好很多,代码也更简洁易读。
内容来源于stack exchange
相关产品推荐
相关产品推荐

