如何设置种子使Polars中sample与map_groups组合后行序一致?
问题原因及解决方法
原因
在Polars v0.19.3中,group_by().map_groups()的分组遍历顺序默认是不确定的——这是因为Polars会并行调度分组处理,线程池的任务调度随机性不受全局随机种子pl.set_random_seed(0)或sample()的seed参数控制。即使每个分组内部的sample结果因固定种子保持一致,分组之间的输出顺序仍会随机变化,最终导致整个grouped_df的行序每次运行都不同。
另外你最初怀疑的pl.read_csv()并行读取不会改变行序——Polars的并行CSV读取是按块读取后拼接,行序和原文件完全一致,所以这个方向的排查是错误的。
高效固定行序的方法(无需排序)
方法1:关闭map_groups的并行处理
直接在map_groups中设置parallel=False,强制Polars按固定顺序遍历分组,结合sample()的固定种子,就能保证最终结果的行序完全一致。
示例代码:
import polars as pl pl.set_random_seed(0) def sample_group(df: pl.DataFrame) -> pl.DataFrame: num_rows = len(df) n = 5 # 假设你要采样的数量 return df.sample(min(n, num_rows), seed=0) # 关闭并行处理 result = df.group_by('fullmtype', 'etype').map_groups(sample_group, parallel=False)
这个方法不需要额外排序操作,性能损失极小(分组数量不多时几乎可忽略),是最直接高效的解决方案。
方法2:固定分组遍历顺序(保留并行)
如果必须保留并行处理,可以先给原数据按分组键做一次稳定的顺序标记,确保分组的遍历顺序固定。这个方法需要额外列操作,但仍比全量排序高效:
示例代码:
# 先给每个分组分配固定的顺序ID df = df.with_row_index().sort(['fullmtype', 'etype', 'index']).drop('index') # 再执行group_by和map_groups result = df.group_by('fullmtype', 'etype').map_groups(sample_group)
这里利用with_row_index()和分组键排序,让原数据的分组顺序固定,后续并行处理时分组的输出顺序也会保持一致。
内容的提问来源于stack exchange,提问作者anilbey
相关产品推荐
相关产品推荐

