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

如何更高效计算DataFrame中重复ID的Diff列?求优化方案

需求与数据集

计算规则

  • 若存在重复ID:
    • 非最后一条重复记录的Diff为当前End_Date与上一条End_Date的天数差值
    • 最后一条重复记录及无重复ID的记录的Diff为End_Date与Start_Date的天数差值

原始数据集

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'ID': [118645, 118985, 119023, 119225, 119225, 119276, 119863, 119924, 119924, 119924, 119924, 119987],
    'Start_Date': ['2021-01-04', '2021-01-11', '2021-01-07', '2021-01-08', '2021-01-08', '2021-01-07', '2021-01-11', '2021-01-13', '2021-01-13', '2021-01-13', '2021-01-13', '2021-01-12'],
    'End_Date': ['2021-04-28', '2022-01-24', '2021-09-08', '2021-04-11', '2021-04-11', '2021-03-16', '2021-03-25', '2021-09-06', '2021-11-09', '2022-05-23', '2022-11-10', '2021-02-23']
})
现有实现方案
df['Diff'] = np.where(df.ID == df.ID.shift(), (pd.to_datetime(df["End_Date"]) - pd.to_datetime(df["End_Date"]).shift()) // np.timedelta64(1, 'D'), None)

df['Diff'] = np.where(df.ID != df.ID.shift(), (pd.to_datetime(df["End_Date"]) - pd.to_datetime(df["Start_Date"])) // np.timedelta64(1, 'D'), df['Diff'])

df_unique = df.drop_duplicates(subset="ID", keep="last")

df_unique['Diff'] = df_unique['End_Date'].sub(df_unique['Start_Date'], axis=0)

df_final = df_unique.combine_first(df)

执行后得到结果:

Index  ID   Start_Date  End_Date    Diff
0    118645 2021-01-04  2021-04-28  114
1    118985 2021-01-11  2022-01-24  378
2    119023 2021-01-07  2021-09-08  244
3    119225 2021-01-08  2021-04-11  93
4    119225 2021-01-08  2021-04-11  93
5    119276 2021-01-07  2021-03-16  68
6    119863 2021-01-11  2021-03-25  73
7    119924 2021-01-13  2021-09-06  236
8    119924 2021-01-13  2021-11-09  64
9    119924 2021-01-13  2022-05-23  195
10   119924 2021-01-13  2022-11-10  666
11   119987 2021-01-12  2021-02-23  42
更优实现方案

通过分组处理简化逻辑,避免多次创建临时DataFrame,步骤更清晰:

# 转换日期列为datetime类型(若原始数据为字符串格式)
df['Start_Date'] = pd.to_datetime(df['Start_Date'])
df['End_Date'] = pd.to_datetime(df['End_Date'])

# 标记每个ID的最后一条记录
df['is_last'] = df.groupby('ID')['End_Date'].transform(lambda x: x == x.iloc[-1])

# 一次性计算Diff列
df['Diff'] = np.where(
    df['is_last'],
    (df['End_Date'] - df['Start_Date']).dt.days,
    (df['End_Date'] - df['End_Date'].shift()).dt.days
)

# 可删除临时标记列
df = df.drop(columns='is_last')

方案优势

  • 逻辑直观:通过分组标记最后一条记录,一次np.where完成所有计算
  • 性能更优:减少中间DataFrame的创建,降低内存占用
  • 代码简洁:行数更少,可读性更强

执行后得到的结果与现有实现完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:32:29