使用Python Pandas cut函数进行分箱时标签与对应值不匹配问题
解决Pandas分箱标签不匹配的问题
你遇到的问题核心是pd.cut的区间开闭逻辑和你的标签定义不匹配,导致数值被分到了错误的区间里。咱们一步步来修正:
错误原因分析
你原来的代码里:
cut_bins = range(2,71,2)生成的区间默认是左开右闭(比如(2,4], (4,6], ..., (68,70])- 加上
include_lowest=True后,第一个区间变成[2,4],所以数值4会被包含到第一个区间,对应标签2-3,这就错了 - 数值70被包含在最后一个区间
(68,70],对应标签68-69,显然也不符合你的预期
修正方案
要让每个标签(比如4-5)正好对应包含4、5的区间,我们需要调整区间的开闭规则,并扩展bins的范围以覆盖70:
1. 调整区间为左闭右开
设置pd.cut的right=False参数,这样区间会变成[2,4), [4,6), ...,完美匹配你定义的2-3(对应2≤x<4)、4-5(对应4≤x<6)这样的标签逻辑。
2. 扩展bins范围覆盖70
原来的range(2,71,2)最后只到70,导致70无法进入70-71的区间,所以我们把bins扩展到72:range(2,72,2),这样最后一个区间是[70,72),对应标签70-71。
3. 同步调整标签范围
标签需要和bins的区间数量一致,所以把labels的生成范围改成range(2,71,2),这样会生成到70-71的标签。
修正后的完整代码
import pandas as pd s = pd.Series([1,4,45,70]) df = pd.DataFrame(s, columns = ['price']) # 生成匹配的标签,覆盖到70-71 labels = ["{0} - {1}".format(i, i + 1) for i in range(2, 71, 2)] # 扩展bins到72,确保70能被分到对应区间 cut_bins = range(2, 72, 2) # 使用right=False设置左闭右开区间 df['price_bins'] = pd.cut(df['price'], bins=cut_bins, labels=labels, right=False) print(df)
运行结果
price price_bins 0 1 NaN 1 4 4 - 5 2 45 44 - 45 3 70 70 - 71
这样每个数值都对应到了正确的分箱标签里~
内容的提问来源于stack exchange,提问作者user3459293




