如何按组计算Pandas DataFrame中两个条件间的时间差?
问题描述
原始Pandas DataFrame如下:
import pandas as pd df = pd.DataFrame({ 'batch': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'd', 'd', 'd', 'd'], 'Code': [100, 120, 130, 120, 100, 140, 150, 150, 100, 100, 130, 130], 'time': pd.to_datetime([ '2019-08-01 00:59:12.000', '2019-08-01 00:59:32.000', '2019-08-01 00:59:42.000', '2019-08-01 00:59:52.000', '2019-08-01 00:44:11.000', '2019-08-02 00:14:11.000', '2019-08-03 00:47:11.000', '2019-09-01 00:44:11.000', '2019-08-01 00:10:00.000', '2019-08-01 00:10:05.000', '2019-08-01 00:10:10.000', '2019-08-01 00:10:20.000' ]) })
需求:
- 按
batch字段分组 - 计算每组中第一个Code为100的记录时间与最后一个Code为130的记录时间的秒数差
- 满足以下任一情况时,结果填充
NaN:- 组内无Code=100的记录
- 组内无Code=130的记录
- 组内最后一个Code=130的时间早于第一个Code=100的时间
期望输出:
batch duration 0 a 30.0 1 b NaN 2 c NaN 3 d 20.0
最优实现方法
方法一:聚合式计算(性能优先)
通过分组聚合一次性提取关键时间点,再统一计算时间差,适合大数据量场景:
# 确保时间列是datetime类型(若原始数据未格式化) df['time'] = pd.to_datetime(df['time']) # 分组提取第一个Code=100、最后一个Code=130的时间 agg_df = df.groupby('batch').agg( first_100=('time', lambda x: x[df['Code'] == 100].min() if (df['Code'] == 100).any() else pd.NA), last_130=('time', lambda x: x[df['Code'] == 130].max() if (df['Code'] == 130).any() else pd.NA) ) # 计算有效秒数差 agg_df['duration'] = agg_df.apply( lambda row: (row['last_130'] - row['first_100']).total_seconds() if pd.notna(row['first_100']) and pd.notna(row['last_130']) and row['last_130'] > row['first_100'] else pd.NA, axis=1 ) # 整理为目标格式 df2 = agg_df[['duration']].reset_index()
方法二:自定义分组函数(逻辑直观)
用groupby.apply封装逻辑,代码可读性更强,便于后续调整规则:
def compute_duration(group): # 获取组内第一个Code=100的时间 first_100 = group[group['Code'] == 100]['time'].min() # 获取组内最后一个Code=130的时间 last_130 = group[group['Code'] == 130]['time'].max() # 校验有效性并返回结果 if pd.isna(first_100) or pd.isna(last_130) or last_130 <= first_100: return pd.NA return (last_130 - first_100).total_seconds() # 执行计算 df['time'] = pd.to_datetime(df['time']) df2 = df.groupby('batch').apply(compute_duration).rename('duration').reset_index()
关键说明
- 两种方法都先确保
time列是datetime类型,这是时间差计算的必要前提 - 方法一通过聚合减少中间计算步骤,在数据量较大时性能更优
- 方法二的自定义函数逻辑清晰,适合需要频繁调整规则的场景
- 最终结果会自动处理所有无效情况,严格符合需求中的
NaN填充规则
内容的提问来源于stack exchange,提问作者Cranjis
相关产品推荐
相关产品推荐

