如何为DataFrame添加布尔列标记邮件是否收到5日内回复?
Pandas实现需求方案
步骤说明
- 先将
Date列转换为datetime类型,确保日期计算有效; - 按
Case_no分组,提取每个工单下Agent发送的所有Response日期; - 为
Email Sent类型的行填充两个布尔列,Response类型的行默认保留NaN; - 针对
Response_Within_Five_Days,需判断是否存在晚于邮件发送日期且在5日内的Agent回复。
完整代码
import pandas as pd # 构建原始数据(如果是读取外部数据,替换为pd.read_csv等方法) df = pd.DataFrame({ 'Case_no': [1,1,1,1,2,2], 'Event_ID': [1,2,3,4,5,6], 'Date': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-10', '2023-01-02', '2023-01-04'], 'Type': ['Email Sent', 'Response', 'Email Sent', 'Response', 'Email Sent', 'Email Sent'], 'Done_by': ['Customer', 'Agent', 'Customer', 'Agent', 'Customer', 'Customer'] }) # 1. 转换日期列为datetime类型 df['Date'] = pd.to_datetime(df['Date']) # 2. 收集每个Case下Agent的Response日期 case_response_dates = df[(df['Type'] == 'Response') & (df['Done_by'] == 'Agent')].groupby('Case_no')['Date'].apply(list) # 3. 初始化新列为NaN df['Response?'] = pd.NA df['Response_Within_Five_Days'] = pd.NA # 筛选Email Sent类型的行 email_mask = df['Type'] == 'Email Sent' # 填充Response?列:判断当前Case是否存在Agent的Response df.loc[email_mask, 'Response?'] = df.loc[email_mask, 'Case_no'].isin(case_response_dates.index) # 4. 定义函数判断是否有5日内的有效回复 def check_5day_response(case_no, email_date): if case_no not in case_response_dates: return False # 遍历该Case的所有Response日期,判断是否有符合条件的 for resp_date in case_response_dates[case_no]: if resp_date >= email_date and (resp_date - email_date).days <= 5: return True return False # 填充Response_Within_Five_Days列 df.loc[email_mask, 'Response_Within_Five_Days'] = df.loc[email_mask].apply( lambda row: check_5day_response(row['Case_no'], row['Date']), axis=1 ) # 查看结果(可选) print(df)
代码解释
- 日期转换:确保后续能正确计算日期差值;
- 分组收集Response日期:避免重复查询,提升效率;
- 布尔列填充:通过
isin快速判断Case是否存在回复; - 5日内回复判断:额外增加
resp_date >= email_date的条件,避免把邮件发送前的旧回复算作有效回复。
内容的提问来源于stack exchange,提问作者brutusbombocloth
相关产品推荐
相关产品推荐

