Polars中int_ranges采样行为疑问:链式与分步调用差异原因
问题解答
链式调用的行为是预期表现吗?
是的,这是Polars的预期行为。
两种调用方式差异的核心原因
Polars里,pl.int_ranges()这类生成表达式的函数,如果直接在链式调用里串联list.sample(),会被当作常量表达式处理——它只会计算一次,生成一个固定的列表,然后把这个列表广播到所有行,所以所有行的采样结果必然相同,都是从同一个固定列表里抽的样本。
而拆分两步操作时,第一步先给每行生成独立的range列:此时pl.int_ranges()是在行级上下文执行,每行都会生成属于自己的range列表;第二步再对每行的range列单独执行list.sample(),相当于每行都做了一次独立的采样操作,自然能得到不同的随机样本。
举个实际代码对比更清楚:
链式调用(所有行样本相同)
import polars as pl df = pl.DataFrame({"id": [1,2,3]}) # 链式调用,采样结果全一致 result_chain = df.with_columns( sample=pl.int_ranges(0, 10).list.sample(3) ) print(result_chain)
拆分两步(每行样本不同)
# 拆分两步,每行采样独立 result_step = df.with_columns( range_col=pl.int_ranges(0, 10) ).with_columns( sample=pl.col("range_col").list.sample(3) ).drop("range_col") print(result_step)
至于用pl.lit包裹参数没用,是因为pl.int_ranges()本身的逻辑就是生成单个常量列表,pl.lit只是把参数转成常量表达式,并没有改变它只生成一次列表的本质。
内容的提问来源于stack exchange,提问作者huangjj27
相关产品推荐
相关产品推荐

