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

Python DataFrame基于列筛选计算日期差及解决total_seconds属性报错

Python处理DataFrame日期差错误的解决方法

问题描述

作为Python新手,处理DataFrame时需要实现以下需求:

  • 针对每个contact_id,计算TYPE_OPER_VALIDATION=3对应的DTHR_OPERATION日期,与TYPE_OPER_VALIDATION=1对应日期的差值
  • 当TYPE_OPER_VALIDATION=3且日期差≤1小时时,新增列填入'connection',否则填'null'

但执行代码时出现"Series' object has no attribute 'total_seconds'"错误,尝试多种方案后仍存在数据类型问题,原代码片段如下:

df_oper_one = merged_table.loc[(merged_table['TYPE_OPER_VALIDATION']==1),['contact_id','TYPE_OPER_VALIDATION','DTHR_OPERATION']]
df_oper_three = merged_table.loc[(merged_table['TYPE_OPER_VALIDATION']==3),['contact_id','TYPE_OPER_VALIDATION','DTHR_OPERATION']]

connection = []
for row in merged_table['contact_id']:
    if (df_validation.loc[(df_validation['TYPE_OPER_VALIDATION']==3)]) & ((pd.to_datetime(df_oper_three['DTHR_OPERATION'],format='%Y-%m-%d %H:%M:%S') - pd.to_datetime(df_oper_one['DTHR_OPERATION'],format='%Y-%m-%d %H:%M:%S').total_seconds()) <= 3600): connection.append('connection')
     # if diff_date.total_seconds() <= 3600: connection.append('connection')
    else:  connection.append('null')

merged_table['connection'] = pd.Series(connection)

错误原因

  1. 错误调用total_seconds():该方法属于单个Timedelta对象,不能直接对Series调用,需用.dt.total_seconds()实现逐元素计算
  2. 逻辑漏洞:循环未针对单个contact_id匹配对应记录,且df_validation变量未定义
  3. 效率低下:遍历contact_id的循环不符合Pandas向量化操作的最佳实践

解决方案

步骤1:统一转换日期列类型

先将DTHR_OPERATION转换为datetime类型,避免重复转换:

merged_table['DTHR_OPERATION'] = pd.to_datetime(merged_table['DTHR_OPERATION'], format='%Y-%m-%d %H:%M:%S')

步骤2:按contact_id聚合日期

用pivot将每个contact_id对应的两种类型日期放到同一行:

pivot_df = merged_table.pivot(
    index='contact_id',
    columns='TYPE_OPER_VALIDATION',
    values='DTHR_OPERATION'
).rename(columns={1: 'date_type1', 3: 'date_type3'})

步骤3:计算日期差并生成目标列

计算日期差的秒数,根据条件生成connection列:

import numpy as np

# 计算日期差秒数,自动处理缺失值
pivot_df['date_diff_seconds'] = (pivot_df['date_type3'] - pivot_df['date_type1']).dt.total_seconds()

# 按条件赋值:存在type3日期且差≤3600秒时填'connection',否则为'null'
pivot_df['connection'] = np.where(
    (pivot_df['date_diff_seconds'] <= 3600) & pivot_df['date_type3'].notna(),
    'connection',
    'null'
)

步骤4:合并回原数据表

将生成的connection列合并到原表,确保仅在TYPE_OPER_VALIDATION=3的行显示结果:

merged_table = merged_table.merge(
    pivot_df[['connection']],
    on='contact_id',
    how='left'
)

# 仅保留TYPE_OPER_VALIDATION=3行的结果,其他行设为'null'
merged_table['connection'] = np.where(
    merged_table['TYPE_OPER_VALIDATION'] == 3,
    merged_table['connection'],
    'null'
)

说明

  • 改用Pandas向量化操作替代循环,大幅提升处理效率
  • 确保每个contact_id的两条记录正确匹配,避免逻辑错误
  • 规范处理日期类型转换,从根源解决数据类型问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:30:52