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

如何按组计算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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:00:56