概述

分组后依旧可以执行「组内累积运算」与「组内排名」等操作,结果保持每组内的顺序逻辑,通常与 transform() 或直接作为 GroupBy 方法使用。


7.1 累积运算:cumsum / cumprod / cummin / cummax

方法说明示例应用
cumsum()组内累积求和累计销售额、累计收入
cumprod()组内累积乘积复利、增长率累积
cummin()组内累积最小值历史最低点
cummax()组内累积最大值历史最高点
import pandas as pd
 
df = pd.DataFrame({
    "部门": ["A", "A", "A", "B", "B", "B"],
    "月份": [1, 2, 3, 1, 2, 3],
    "销售额": [1000, 1500, 1200, 2000, 1800, 2500],
})
 
df["累计销售额"] = df.groupby("部门")["销售额"].cumsum()
df["累计最大值"] = df.groupby("部门")["销售额"].cummax()
df["累计最小值"] = df.groupby("部门")["销售额"].cummin()
df["累计乘积"]   = df.groupby("部门")["销售额"].cumprod()
 
# 在 agg / transform 中使用累积函数
df.groupby("部门")["销售额"].transform("cumsum")
 
# 多列累积
df.groupby("部门")[["销售额"]].cumsum()

所有累积方法支持 axis 参数(SeriesGroupBy 通常只支持 axis=0)。


7.2 cumcount()

cumcount() 返回每个组内从 0 开始的累计行号,常用于生成组内序号、分组抽样、透视前处理。

df["组内序号"] = df.groupby("部门").cumcount()          # 0, 1, 2, 0, 1, 2
df["组内序号+1"] = df.groupby("部门").cumcount(ascending=True) + 1
 
# 从每组末尾开始计数
df["组内倒序"] = df.groupby("部门").cumcount(ascending=False)
 
# 多列分组
df.groupby(["部门", "月份"]).cumcount()

7.3 rank()

rank() 为每组中的元素计算排名。

常用参数

参数默认值说明
method"average"排名方式:"average"、"min"、"max"、"first"、"dense"
ascendingTrue升序排名
pctFalse是否返回百分比排名
na_option"keep""keep"、"top"、"bottom"
axis0排名轴向
df["销售排名"] = df.groupby("部门")["销售额"].rank()               # 默认平均排名
df["销售排名_min"] = df.groupby("部门")["销售额"].rank(method="min")
df["销售排名_dense"] = df.groupby("部门")["销售额"].rank(method="dense")
df["销售排名_desc"] = df.groupby("部门")["销售额"].rank(ascending=False)
df["销售排名_pct"] = df.groupby("部门")["销售额"].rank(pct=True)
 
# 多列排名
df.groupby("部门")[["销售额"]].rank()

7.4 shift()

shift() 对每个组内的值沿时间/顺序轴移动,常用于计算「上一期值」「环比/同比」。

df["上期销售额"] = df.groupby("部门")["销售额"].shift(1)     # 前一期的值
df["下期销售额"] = df.groupby("部门")["销售额"].shift(-1)    # 后一期的值
df["销售额环比"] = df.groupby("部门")["销售额"].pct_change()  # 见 diff 部分
 
# shift 参数:periods、freq、fill_value
df.groupby("部门")["销售额"].shift(periods=2, fill_value=0)

7.5 diff()

diff() 计算组内相邻行之间的差值,常与 shift() 配合使用。

df["销售额差值"] = df.groupby("部门")["销售额"].diff()          # 当前行 - 上一行
df["销售额差值2"] = df.groupby("部门")["销售额"].diff(2)        # 与两期前比较
df["销售额变化率"] = df.groupby("部门")["销售额"].pct_change()   # 百分比变化

组合示例:累计 + 排名 + 差分

df = df.assign(
    累计销售额=df.groupby("部门")["销售额"].cumsum(),
    组内排名=df.groupby("部门")["销售额"].rank(method="dense", ascending=False),
    环比差值=df.groupby("部门")["销售额"].diff(),
    环比增长率=df.groupby("部门")["销售额"].pct_change() * 100,
    组内序号=df.groupby("部门").cumcount() + 1,
)

相关笔记