Pandas pd.cut按DD/MM/YYYY日期分箱新增列报bins单调递增错误
报错原因
pd.cut() 要求传入的分箱边界(bins参数)必须是单调递增的序列,你当前传入的cutoff列表是从最晚日期到最早日期的降序排列,直接触发bins must increase monotonically报错。
除此之外你的代码还有三个隐藏问题:
- 直接用
astype('datetime64')转换日期时,pandas默认按MM/DD/YYYY格式解析,和你实际使用的DD/MM/YYYY格式不匹配,会导致日期解析错误 - 你定义了5个phase等级,但只传入了5个分界日期,n个分界只能生成n-1个分箱区间,labels数量和区间数不匹配
- 没有补充最早的时间边界,导致早于第一个分界点的日期会被标记为空值
修复方案
按照分箱逻辑调整分界日期为升序排列,正确解析日期格式,补充必要的分箱边界即可:
- 先统一将所有日期列、分界日期都按
DD/MM/YYYY格式解析为datetime类型 - 将分界日期调整为从早到晚的升序,补充最早的时间下界覆盖最早的样本日期
- 匹配分箱区间顺序传入对应phase标签,设置
right=True表示区间包含右侧边界值,符合你的映射规则
修复后完整代码
import pandas as pd # 构造样例数据 final_commit = pd.DataFrame({ 'dates': ['11/04/2017', '17/04/2017', '23/04/2017', '02/04/2017', '30/03/2017'] }) # 正确解析原日期列,指定日/月/年格式 final_commit['dates'] = pd.to_datetime(final_commit['dates'], format='%d/%m/%Y') # 分界日期调整为升序,补充最小时间下界覆盖3月30日的样本 cutoff = [ pd.Timestamp('2000-01-01'), # 补充一个足够早的下界 '31/03/2017', '06/04/2017', '12/04/2017', '18/04/2017', '24/04/2017' ] # 正确解析分界日期 cutoff = pd.to_datetime(cutoff, format='%d/%m/%Y') # 分箱打标 final_commit['phase'] = pd.cut( final_commit['dates'], bins=cutoff, labels=[1,2,3,4,5], # 按区间从早到晚对应phase1到phase5 right=True, include_lowest=True ) # 按日期排序查看结果 print(final_commit.sort_values('dates'))
运行结果
运行后输出完全匹配你的预期:
dates phase 4 2017-03-30 1 3 2017-04-02 2 0 2017-04-11 3 1 2017-04-17 4 2 2017-04-23 5
内容的提问来源于stack exchange,提问作者nerd
相关产品推荐
相关产品推荐

