You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas中使用to_datetime避免生成时间戳并按日期区间分组时出现TypeError问题的解决问询

解决日期区间匹配错误并实现无时间戳的时段分组

首先,咱们先揪出报错的直接原因:你在定义掩码的时候,把日期变量date1、date2这些用单引号包起来变成了字符串'date1',而你的question_date是datetime.date类型,字符串和日期类型当然没法用>=、<比较,这就触发了TypeError。

接下来咱们一步步修正并优化你的代码,完全满足你的需求:

第一步:正确处理日期列,彻底去除时间戳

首先要确保日期列是不带时间的纯日期格式,可以这样处理:

import pandas as pd

# 初始化你的DataFrame
df3 = pd.DataFrame(
    [['23.02.2012', '23.02.2012', 'aaa'], 
     ['27.02.2014', '27.02.2014', 'bbb'], 
     ['17.08.2018', '17.08.2018', 'ccc'], 
     ['22.07.2019', '22.07.2019', 'ddd']], 
    columns=['date', 'period', 'text']
)

# 把date列转换为datetime类型后,提取纯日期部分(彻底去掉时间戳)
df3['date'] = pd.to_datetime(df3['date'], errors='coerce').dt.date
# 同步处理question_date列(假设它是从date衍生的)
df3['question_date'] = df3['date']

这里用.dt.date把datetime类型转换成纯日期的datetime.date对象,完全消除了时间戳的干扰。

第二步:修正掩码定义,正确使用日期变量

现在定义日期阈值时保持纯日期格式,然后定义掩码时直接用变量名,不要加引号:

# 定义纯日期格式的阈值
date1 = pd.Timestamp('1990-10-14').date()
date2 = pd.Timestamp('1994-11-10').date()
date3 = pd.Timestamp('1999-10-01').date()
date4 = pd.Timestamp('2004-06-13').date()
date5 = pd.Timestamp('2009-08-30').date()
date6 = pd.Timestamp('2014-10-14').date()
date7 = pd.Timestamp('2019-11-26').date()
date8 = pd.Timestamp('2021-09-20').date()

# 正确定义掩码(注意不要给变量加引号!)
mask1 = (df3['question_date'] >= date1) & (df3['question_date'] < date2)
mask2 = (df3['question_date'] >= date2) & (df3['question_date'] < date3)
mask3 = (df3['question_date'] >= date3) & (df3['question_date'] < date4)
mask4 = (df3['question_date'] >= date4) & (df3['question_date'] < date5)
mask5 = (df3['question_date'] >= date5) & (df3['question_date'] < date6)
mask6 = (df3['question_date'] >= date6) & (df3['question_date'] < date7)
mask7 = (df3['question_date'] >= date7) & (df3['question_date'] < date8)

# 为匹配的日期区间赋值时段
df3.loc[mask1, 'leg_per'] = '1990-1994'
df3.loc[mask2, 'leg_per'] = '1994-1999'
df3.loc[mask3, 'leg_per'] = '1999-2004'
df3.loc[mask4, 'leg_per'] = '2004-2009'
df3.loc[mask5, 'leg_per'] = '2009-2014'
df3.loc[mask6, 'leg_per'] = '2014-2019'
df3.loc[mask7, 'leg_per'] = '2019-2021'

现在两边都是datetime.date类型,可以正常比较,不会再触发类型错误。

第三步:更高效的替代方案——使用pd.cut

如果你的日期区间是连续且有序的,用pd.cut会比手动写多个掩码更简洁,代码量更少也不容易出错:

# 定义区间边界和对应的时段标签
bins = [date1, date2, date3, date4, date5, date6, date7, date8]
labels = ['1990-1994', '1994-1999', '1999-2004', '2004-2009', '2009-2014', '2014-2019', '2019-2021']

# 直接生成leg_per列
df3['leg_per'] = pd.cut(
    pd.to_datetime(df3['question_date']),  # 转换为datetime64类型适配pd.cut
    bins=pd.to_datetime(bins),
    labels=labels,
    include_lowest=True  # 包含左边界
)

这里把datetime.date转换回datetime64[ns]类型(pd.to_datetime自动处理),因为pd.cut更适配pandas的datetime类型,最终结果和手动掩码的方式完全一致,但代码更简洁。

验证结果

运行完上面的代码后,你的df3的leg_per列会根据question_date的区间正确赋值:

  • 23.02.2012 → 2009-2014
  • 27.02.2014 → 2014-2019
  • 17.08.2018 → 2014-2019
  • 22.07.2019 → 2014-2019

完全符合你的需求,且不会有时间戳的干扰。

内容的提问来源于stack exchange,提问作者id345678

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:37:33