如何在主DataFrame中为每个CallID匹配填充计算的Time Delta
问题与解决方案
原始DataFrame
| CallID | StorageDate | CloseDate | Time Delta |
|---|---|---|---|
| 1 | 2023-02-08 14:35:09 | 2023-02-08 14:35:56 | |
| 1 | 2023-02-08 14:35:56 | 2023-02-08 14:42:00 | value |
| 2 | 2023-02-07 10:17:18 | 2023-02-07 10:22:23 | |
| 2 | 2023-02-07 10:22:23 | 2023-02-07 15:09:14 | |
| 2 | 2023-02-07 15:09:14 | 2023-02-07 16:20:50 | |
| 2 | 2023-02-07 16:20:49 | 2023-02-08 09:23:16 | |
| 2 | 2023-02-08 09:23:16 | 2023-02-08 09:27:21 | value |
| 3 | 2023-03-10 10:31:25 | 2023-03-10 10:41:37 | |
| 3 | 2023-03-10 10:41:37 | 2023-03-10 14:23:18 | value |
需求
为每个CallID计算最后一条记录的CloseDate与第一条记录的StorageDate的时间差,将结果填入对应CallID的目标行(即Time Delta标注为value的行)。
高效解决方案
步骤1:确保日期列是datetime类型
如果原始数据的日期列是字符串格式,先转换为datetime类型:
import pandas as pd df['StorageDate'] = pd.to_datetime(df['StorageDate']) df['CloseDate'] = pd.to_datetime(df['CloseDate'])
步骤2:分组计算并批量赋值
方案一:基于"value"标记行赋值
直接定位Time Delta为value的行,结合分组计算的时间差批量填充:
# 计算每个CallID的时间差,生成CallID与时间差的映射字典 delta_map = df.groupby('CallID').apply( lambda group: group.iloc[-1]['CloseDate'] - group.iloc[0]['StorageDate'] ).to_dict() # 定位目标行并赋值 df.loc[df['Time Delta'] == 'value', 'Time Delta'] = df['CallID'].map(delta_map)
方案二:基于组最后一行赋值
如果目标行是每个CallID的最后一行,可直接通过分组获取最后一行索引赋值:
# 计算每个CallID的时间差 delta_map = df.groupby('CallID').apply( lambda group: group.iloc[-1]['CloseDate'] - group.iloc[0]['StorageDate'] ).to_dict() # 获取每个CallID最后一行的索引 last_row_indices = df.groupby('CallID').tail(1).index df.loc[last_row_indices, 'Time Delta'] = df['CallID'].map(delta_map)
关键说明
- 上述方案使用Pandas向量化分组操作,避免了逐CallID循环的低效问题,处理16821个CallID的大数据量时性能远优于循环。
- 直接在主DataFrame上完成赋值,无需操作子DataFrame,避免数据同步问题。
内容的提问来源于stack exchange,提问作者Gustavo Felippe de Oliveira
相关产品推荐
相关产品推荐

