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

Pandas日期做差筛选超30天账户数据报TypeError如何解决

问题说明

现有如下结构的DataFrame df1:

Acc_id   Acc_name   Acc_end_date
qqq-1    test1      12/31/2021
www-2    test2      05/28/2022
yyy-6    test3      06/15/2022
zzz-6    test4      06/17/2022
kkk-6    test5      03/16/2022

其中Acc_end_date字段存储日期值,需求为筛选出截止今日,Acc_end_date对应日期已过去30天以上的账户ID。
原有实现代码触发两类报错:

  1. 第一版代码报错:TypeError: unsupported operand type(s) for -: 'DatetimeArray' and 'list'
  2. 调整后代码报错:TypeError: unsupported operand type(s) for -: 'DatetimeArray' and 'datetime.date'
报错根因
  • 第一版错误:代码中np.array(todays_date)没有将转换结果赋值回原变量,实际参与运算的还是Python原生列表,pandas的DatetimeArray不支持直接和list做减法运算;且循环生成重复日期列表的写法完全冗余,pandas原生支持标量广播运算,不需要手动构造等长数组。
  • 第二版错误:pd.to_datetime转换后的列是datetime64[ns]时间戳类型,而date.today()返回的是Python原生date对象,二者精度、类型均不匹配,无法直接运算;同时代码中引用了未定义的only_inactive变量,也会触发额外错误。
  • 逻辑错误:原有代码写反了日期运算的减数、被减数顺序,且日期做差得到的是Timedelta类型,直接和整数30比较存在类型兼容问题,就算类型匹配也会得到全为False的筛选结果。
正确实现

不需要循环构造日期数组,直接使用pandas兼容的时间类型做运算即可,完整代码如下:

import pandas as pd

# 转换列为datetime类型,显式指定日期格式避免解析错误,如果是两位年份把%Y改成%y即可
df1['Acc_end_date'] = pd.to_datetime(df1['Acc_end_date'], format='%m/%d/%Y')

# 获取和列类型兼容的当日日期,normalize()将时间重置为当日0点,避免时分秒带来的计算误差
today = pd.Timestamp.today().normalize()

# 计算日期间隔天数,筛选已过期超过30天的记录
df2 = df1[(today - df1['Acc_end_date']).dt.days > 30]

关键注意点:

  • 调用pd.to_datetime时显式传入format参数,既可以避免pandas自动解析时出现月、日颠倒的错误,也能大幅提升大数据集下的转换效率。
  • 用pd.Timestamp.today()替代原生date.today(),返回值类型和DataFrame中datetime列完全匹配,不需要额外做类型转换。
  • 日期做差后通过.dt.days取出间隔的天数值,再和30做数值比较,规避Timedelta类型和整数直接比较的兼容问题。
  • 运算顺序为「今日日期 - 账户结束日期」,得到的是账户结束日期距离今日过去的天数,符合筛选逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:21:21