如何用Polars实现与pandas.cut一致的列分箱行为?
在Polars中复现pandas.cut的分箱行为(超出范围值设为Null)
问题场景
给定分数列表 scores = [1111, 65, 88, -1111, 92] 和断点 breaks = [0, 50, 60, 70, 80, 90, 100]:
pandas.cut会将超出断点范围的值(如1111、-1111)对应的分箱设为Nullpolars.Series.cut默认会自动生成(-inf, 0]和(100, inf]这类包含无穷的区间,而非Null
需实现Polars与pandas.cut完全一致的分箱效果。
解决方案
方法1:使用include_outer_boundaries=False参数(推荐)
Polars的cut方法提供了include_outer_boundaries参数,设置为False后,会严格遵循给定断点生成区间,超出范围的值直接返回Null,完全匹配pandas.cut的默认行为:
import polars as pl scores = [1111, 65, 88, -1111, 92] breaks = [0, 50, 60, 70, 80, 90, 100] s = pl.Series(scores) result = s.cut(breaks, include_outer_boundaries=False) print(result)
输出结果:
shape: (5,) Series: 'scores' [cat] [ null (60, 70] (80, 90] null (90, 100] ]
方法2:手动过滤含无穷的区间(兼容旧版本)
若使用的Polars版本低于0.18.0(该版本才引入include_outer_boundaries参数),可先执行默认分箱,再将包含无穷的区间替换为Null:
import polars as pl scores = [1111, 65, 88, -1111, 92] breaks = [0, 50, 60, 70, 80, 90, 100] s = pl.Series(scores) # 执行默认分箱 result = s.cut(breaks) # 替换含无穷的区间为Null result = result.map_elements( lambda x: x if "-inf" not in str(x) and "inf" not in str(x) else None, return_dtype=pl.Categorical ) print(result)
输出结果与方法1完全一致。
说明
- 方法1是最优解,代码简洁且性能更优,无需额外的过滤操作
- 方法2作为兼容方案,通过字符串匹配识别含无穷的区间,适合无法升级Polars版本的场景
内容的提问来源于stack exchange,提问作者tdy
相关产品推荐
相关产品推荐

