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

pandas DataFrame按ID分组计算不同行列值差值的高效实现方法

问题描述

现有如下结构的pandas DataFrame:

Timestamp   ID      X X Diff       Y Y Diff
0              0  100  1.728   None  14.378   None
1             12  100  2.035   None  14.378   None
2             24  100  2.342   None  14.378   None
3             36  100  2.630   None  14.378   None
4             48  100  2.937   None  14.416   None

需要计算相邻行的X、Y列值的差值,填入对应的X Diff和Y Diff列,最终效果如下:

Timestamp   ID      X X Diff       Y Y Diff
0           0  100  1.728   None  14.378   None
1          12  100  2.035  0.307  14.378      0
2          24  100  2.342  0.307  14.378      0
3          36  100  2.630  0.288  14.378      0
4          48  100  2.937  0.307  14.416  0.038

计算规则:只有当前行与上一行ID相同时才计算差值,若为分组首行或相邻行ID不同,对应Diff列保留None。

目前已实现的for循环版本代码如下,在10万行以上数据量下运行效率极低:

def getDifferences(dataframe, column):
    for i in range(19):
        startValue = dataframe.iloc[i][column]
        endValue = dataframe.iloc[i+1][column]
    
        diff = endValue - startValue
        if column == "X":
            dataframe.at[i+1, "X Diff"] = diff
        else:
            dataframe.at[i+1, "Y Diff"] = diff

已知数据已清洗,每个ID固定对应20条连续记录,需要更优雅高效的实现方案。

解决方案

pandas自带的分组差分方法即可满足需求,完全不需要自定义循环,性能优异:

import pandas as pd

# 按ID分组后对指定列计算相邻行差值
df['X Diff'] = df.groupby('ID')['X'].diff()
df['Y Diff'] = df.groupby('ID')['Y'].diff()

# 若需要将默认的NaN替换为None,执行以下代码即可
df = df.where(pd.notnull(df), None)

说明:

  • 该实现是向量化运算,底层为C语言实现,10万行数据处理耗时仅为毫秒级,远快于Python层的for循环实现
  • groupby操作保证差值计算仅在同ID分组内执行,不会出现跨ID计算的问题,天然符合需求规则
  • 每个分组的第一行没有前序行,diff方法会自动返回空值,和需求的首行保留None的要求一致

如果需要更极致的性能,也可以使用纯numpy实现,跳过groupby的分组开销:

import numpy as np

x = df['X'].values
y = df['Y'].values
ids = df['ID'].values

# 计算X差值,非连续ID位置设为空
x_diff = np.concatenate([[np.nan], x[1:] - x[:-1]])
x_diff[ids[1:] != ids[:-1]] = np.nan
df['X Diff'] = x_diff

# 计算Y差值,非连续ID位置设为空
y_diff = np.concatenate([[np.nan], y[1:] - y[:-1]])
y_diff[ids[1:] != ids[:-1]] = np.nan
df['Y Diff'] = y_diff

# 可选替换NaN为None
df = df.where(pd.notnull(df), None)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 15:00:03