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

同一DataFrame列内日期对比及标签匹配问题求助

订单与呼叫数据标签匹配需求

我在同一DataFrame中存储了订单数据与呼叫数据,需要实现以下逻辑:

  • 对比「Order created」的START时间与「Call Start」相关行的START时间
  • 若呼叫的START时间在订单创建后30天内,将该订单的Tag_x和Tag_z值添加到对应的呼叫行
  • 若存在多个符合条件的「Order created」记录,需以「Tagx1, Tagx2...」的格式拼接标签值

我尝试将原DataFrame拆分为订单子表(dforder)和呼叫子表(dfcall),使用iterrows()遍历行进行判断,但不确定该方法的使用是否正确。以下是样本数据、期望输出及我编写的代码片段:

样本数据

CASE IDActivity NameSTARTminit_source_systemTag_xTag_z
111Order createdTuesday, March 16, 2021NCHome Phone InstallationVOICE
111Fielded Work Order OpenTuesday, March 16, 2021FWDSHome Phone InstallationVOICE
111Job - COMPLETETuesday, March 16, 2021FWDSHome Phone InstallationVOICE
111Fielded Work Order CompletedThursday, March 18, 2021FWDSHome Phone InstallationVOICE
111Order createdWednesday, May 4, 2022NCHome Security InstallationSECURITY
111Fielded Work Order OpenWednesday, May 4, 2022FWDSHome Security InstallationSECURITY
111Job - COMPLETEWednesday, May 4, 2022FWDSHome Security InstallationSECURITY
111Fielded Work Order CompletedThursday, May 5, 2022FWDSHome Security InstallationSECURITY
111Bill IssuedTuesday, May 10, 2022
111Call StartTuesday, May 17, 2022Gen
111PureFibre-TSTuesday, May 17, 2022Gen

期望输出

CASE IDActivity NameSTARTminit_source_systemTag_xTag_z
111Order createdTuesday, March 16, 2021NCHome Phone InstallationVOICE
111Fielded Work Order OpenTuesday, March 16, 2021FWDSHome Phone InstallationVOICE
111Job - COMPLETETuesday, March 16, 2021FWDSHome Phone InstallationVOICE
111Fielded Work Order CompletedThursday, March 18, 2021FWDSHome Phone InstallationVOICE
111Order createdWednesday, May 4, 2022NCHome Security InstallationSECURITY
111Fielded Work Order OpenWednesday, May 4, 2022FWDSHome Security InstallationSECURITY
111Job - COMPLETEWednesday, May 4, 2022FWDSHome Security InstallationSECURITY
111Fielded Work Order CompletedThursday, May 5, 2022FWDSHome Security InstallationSECURITY
111Bill IssuedTuesday, May 10, 2022
111Call StartTuesday, May 17, 2022GenHome Phone Installation, Home Security InstallationVOICE, SECURITY
111PureFibre-TSTuesday, May 17, 2022GenHome Phone Installation, Home Security InstallationVOICE, SECURITY

尝试代码

dfcall= df[df['Activity Name']=="Call Start"]
dfcall['Tag_x']=nan
dfcall['Tag_z']=nan
dfcall=dfcall[['CASE ID','Activity Name','START','Tag_x','Tag_z']].reset_index(drop=True)
dforder=df[df['Activity Name']=="Order created"].reset_index(drop=True)
dforder=dforder[['CASE ID','Activity Name','START','Tag_x','Tag_z']].reset_index(drop=True)

for index, row_c in dfcall.iterrows():
for index, row_o in dforder.iterrows():
    if (row_c['CASE ID']==row_o['CASE ID']) & (row_c['START']>row_o['START'])& (((row_c['START'] - row_o['START']).total_seconds()/60/60)<=720): 
        y=row_o['Tag_x']
        row_c['Tag_x']=y+" "+"|"+" "+row_o['Tag_x']

问题分析与优化方案

原代码存在的问题

  1. 时间格式未转换:START列是字符串格式,无法直接进行时间比较和运算,必须先转换为datetime类型。
  2. iterrows()效率低下:双重iterrows()循环在数据量较大时性能极差,应使用向量化操作替代。
  3. 标签拼接逻辑错误:原代码会重复拼接同一个标签,且格式不符合逗号分隔的要求。
  4. 遗漏关联行:需求中需更新「Call Start」及同时间的「PureFibre-TS」行,原代码仅处理了前者。

优化实现代码

import pandas as pd

# 1. 转换START列为datetime类型,确保时间运算有效
df['START'] = pd.to_datetime(df['START'], format='%A, %B %d, %Y')

# 2. 提取订单数据,计算订单创建后30天的截止时间
order_df = df[df['Activity Name'] == 'Order created'].copy()
order_df['30_days_limit'] = order_df['START'] + pd.Timedelta(days=30)

# 3. 定位所有需要更新的行:Call Start及其同时间的关联行
call_time = df[df['Activity Name'] == 'Call Start']['START'].iloc[0]
update_mask = (df['Activity Name'] == 'Call Start') | (df['START'] == call_time)
update_df = df[update_mask].copy()

# 4. 关联订单与待更新数据,筛选符合时间条件的记录
merged_data = pd.merge(
    update_df,
    order_df[['CASE ID', 'START', 'Tag_x', 'Tag_z', '30_days_limit']],
    on='CASE ID',
    suffixes=('_call', '_order')
)
valid_matches = merged_data[(merged_data['START_call'] >= merged_data['START_order']) 
                            & (merged_data['START_call'] <= merged_data['30_days_limit'])]

# 5. 按呼叫行分组,拼接标签值
aggregated_tags = valid_matches.groupby(['CASE ID', 'START_call', 'Activity Name', 'minit_source_system']).agg(
    Tag_x=('Tag_x', lambda x: ', '.join(x)),
    Tag_z=('Tag_z', lambda x: ', '.join(x))
).reset_index()

# 6. 将拼接后的标签更新回原DataFrame
df.update(aggregated_tags.set_index(['CASE ID', 'Activity Name', 'START']))

# 输出结果
print(df)

代码说明

  • 时间转换:通过pd.to_datetime将字符串时间转为可计算的datetime类型,保证时间比较逻辑正确。
  • 高效关联:使用merge替代双重循环,大幅提升数据处理效率。
  • 标签聚合:利用groupby结合lambda函数实现标签的逗号分隔拼接,符合需求格式。
  • 批量更新:通过update方法将结果同步回原DataFrame,确保所有关联行都被正确更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:55:24