Pandas使用to_datetime转换后period列混合类型导致排序报错如何解决
回答
问题根因
- 日期区间未全覆盖:你定义的7个mask的最大截止日期为
2021-9-20,那100行异常数据的date值都晚于这个时间,没有匹配到任何赋值规则,因此period列保留了最开始赋值的Timestamp类型的日期值,最终period列同时存在字符串、Timestamp两种数据类型,排序时无法跨类型比较触发报错。 - 转
dt.date报错的原因:dt.date返回的是Python原生datetime.date类型,后续和字符串格式的日期边界(如'2021-9-20')直接比较时,pandas不支持这两种类型的比较操作,因此触发类型错误。
解决方案
推荐用pd.cut方法替代手动写多组mask,代码更简洁且不易漏边界,还能统一返回字符串类型的周期标签,完全对齐你原有的左闭右开区间判断逻辑:
import pandas as pd # 1. 完成date列的日期转换 df3['date'] = pd.to_datetime(df3['date'], errors='coerce') # 2. 定义所有日期边界和对应的周期标签,按需补充后续区间即可 date_bins = [ pd.to_datetime('1990-10-14'), pd.to_datetime('1994-11-10'), pd.to_datetime('1999-10-1'), pd.to_datetime('2004-6-13'), pd.to_datetime('2009-8-30'), pd.to_datetime('2014-10-14'), pd.to_datetime('2019-11-26'), pd.to_datetime('2021-9-20'), pd.to_datetime('2100-12-31') # 补充足够大的边界,覆盖所有晚于2021-9-20的日期 ] period_labels = [ '1990-1994', '1994-1999', '1999-2004', '2004-2009', '2009-2014', '2014-2019', '2019-2021', '2021及以后' # 对应晚于2021-9-20的周期标签,可按实际需求修改 ] # 3. right=False对齐原有左闭右开的区间判断逻辑,生成的period全为字符串类型 df3['period'] = pd.cut(df3['date'], bins=date_bins, labels=period_labels, right=False) # 4. 移动period列到指定位置的逻辑保持不变 col_name = 'period' strt_col = df3.pop(col_name) df3.insert(5, col_name, strt_col) # 5. 此时period列全为字符串,排序不会报错 df3 = df3.sort_values(by = ['period'])
如果不想改动原有mask逻辑,只需在mask7赋值完成后加一行兜底赋值即可解决问题:
# 给所有未匹配到规则、period仍为Timestamp类型的行赋值默认标签 df3.loc[df3['period'].apply(lambda x: isinstance(x, pd.Timestamp)), 'period'] = '2021及以后'
内容的提问来源于stack exchange,提问作者id345678
相关产品推荐
相关产品推荐

