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

如何在Pandas GroupBy中用一行代码结合pct_change与cumprod计算

Pandas GroupBy分组下基于组首元素计算累计涨跌幅的简洁实现

在Pandas的GroupBy分组处理场景中,需要基于每组的首个元素计算累计涨跌幅(类似全局pct_change后cumprod的效果,但按组独立计算)。现有代码可运行但分成了两步GroupBy操作,想简化成一行代码实现。

原代码

import pandas as pd
import numpy as np

data = [[1, 10], [2, 17], [3, 15],[4, 11], [5, 17], [6, 15]]
df = pd.DataFrame(data, columns=["id", "open"])

# 全局累计涨跌幅
df['Normal'] = df['open'].pct_change().fillna(0).add(1).cumprod().sub(1).mul(100).round(2)

# 分组计算(分两步)
df["Group_of_3"] = df.groupby(np.arange(len(df)) // 3 )["open"].pct_change().fillna(0).add(1)
df["Group_of_3"] = df.groupby(np.arange(len(df)) // 3 )["Group_of_3"].cumprod().sub(1).mul(100).round(2)

print(df)

原输出结果

id  open  Normal  Group_of_3
0   1    10     0.0        0.00
1   2    17    70.0       70.00
2   3    15    50.0       50.00
3   4    11    10.0        0.00
4   5    17    70.0       54.55
5   6    15    50.0       36.36

优化方案

方案1:直接基于组内首元素计算(性能更优)

跳过pct_change和cumprod的组合,直接用每组的open值与组内首个元素做比值计算,一步完成所有转换:

df["Group_of_3"] = df.groupby(np.arange(len(df)) // 3)["open"].transform(
    lambda x: (x / x.iloc[0] - 1).mul(100).round(2)
)

方案2:链式调用原逻辑(保留原有计算步骤)

如果要严格遵循原代码的pct_change→cumprod逻辑,可通过groupby.apply将每组的处理逻辑封装为lambda函数,一次性完成操作:

df["Group_of_3"] = df.groupby(np.arange(len(df)) // 3)["open"].apply(
    lambda x: x.pct_change().fillna(0).add(1).cumprod().sub(1).mul(100).round(2)
).reset_index(drop=True)

说明

  • 方案1的计算逻辑更直接,避免了多次累计乘积运算,性能更高效,且输出结果与原代码完全一致。
  • 方案2完整保留原有的计算链路,适合需要严格对齐原逻辑的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:52:39