使用pd.cut时部分有效值被归类为nan的问题排查
问题描述
使用pd.cut对数值进行分桶时,多数数据可正常归类,但部分明确有效值被标记为nan。示例DataFrame如下:
numbers difference_interval 0 0.000000e+00 nan 1 3.263739e-03 nan 2 3.637279e-02 nan 3 5.308298e-03 nan 4 -1.139971e-01 nan 5 nan nan
创建区间的代码如下:
bins = pd.IntervalIndex.from_tuples([(-1, -.2), (-.2, -.1), (-.1, -.05), (-.05, 0), (0, .05), (0.05, .1), (0.1, .2), (0.2, 1)]) col = 'numbers' df = (df.dropna(subset=col) .assign(difference_interval= lambda df: pd.cut(df[col].values, bins).sort_values().astype(str))) df.query('difference_interval == "nan"')
问题原因分析
- 分桶结果与原数据错位:在
pd.cut之后调用了.sort_values(),打乱了分桶结果的顺序,导致分桶后的区间无法与原DataFrame的行一一对应,原本能正确匹配的数值也被错误赋值为nan。 - 区间边界未覆盖所有有效值:
pd.IntervalIndex.from_tuples默认采用左闭右开的区间规则(closed='right'),使得部分数值落在区间间隙中:- 例如数值
0.0,既不属于(-.05, 0)(右开规则不包含0),也不属于(0, .05)(左开规则不包含0),直接被标记为nan; - 若数值恰好等于区间的右边界(如
-0.1、0.05等),同样会因左闭右开规则无法匹配到对应区间。
- 例如数值
修正方案
- 移除
.sort_values(),确保分桶结果与原数据顺序一致:
df = (df.dropna(subset=col) .assign(difference_interval= lambda df: pd.cut(df[col], bins).astype(str)))
- 调整区间规则或边界,覆盖所有有效值:
- 方式一:修改区间端点填补间隙,例如将
(-.05, 0)改为(-.05, 0],(0, .05)改为[0, .05),确保0被包含在区间内; - 方式二:创建
IntervalIndex时指定闭合规则,比如设置closed='both'(全闭区间),根据需求调整:bins = pd.IntervalIndex.from_tuples([(-1, -.2), (-.2, -.1), (-.1, -.05), (-.05, 0), (0, .05), (0.05, .1), (0.1, .2), (0.2, 1)], closed='both')
- 方式一:修改区间端点填补间隙,例如将
内容的提问来源于stack exchange,提问作者geds133
相关产品推荐
相关产品推荐

