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

如何使用Pandas groupby的apply/transform按组计算相对值?

解决按年份组计算相对值的问题

首先明确你的需求:对每个年份组,以该组中rank=1的value作为基准值,计算组内每个value与基准值的比值生成value_relative列,同时保留原有的NaN值。

你的原始DataFrame及初始化代码如下:

import numpy as np
import pandas as pd
df = pd.DataFrame({'year': [1990,1990,1992,1992,1992], 
                   'value': [100,200,300,400,np.nan], 
                   'rank': [2,1,2,1,3]})

分析你尝试代码的问题

你写的代码:

df['value_relative'] = df.groupby('year')['value'].transform(lambda x: x/x[x.rank == 1]['value'])

这里的核心问题是:x.rank调用的是Pandas Series内置的rank()方法(用于计算数值的排名),而非你DataFrame中名为rank的列。这导致你无法正确筛选出每组中rank=1的行,自然得不到正确的基准值。

正确的实现方法

这里提供两种简洁高效的解法:

方法1:使用groupby.apply处理每组

这种方法逻辑直观,适合需要对每组做复杂自定义处理的场景:

def calculate_relative(group):
    # 获取当前组中rank=1的value作为基准(假设每组仅存在一个rank=1的行)
    base_value = group.loc[group['rank'] == 1, 'value'].iloc[0]
    # 计算相对值,原数据中的NaN会自动保留
    group['value_relative'] = group['value'] / base_value
    return group

df = df.groupby('year').apply(calculate_relative)

方法2:先提取基准值再映射

这种方法执行效率更高,适合基准值规则明确的场景:

# 提取每个年份对应的rank=1的value,构建年份-基准值的映射
year_base_map = df[df['rank'] == 1].set_index('year')['value']
# 通过year列映射基准值,再计算相对值
df['value_relative'] = df['value'] / df['year'].map(year_base_map)

最终输出

两种方法都会生成你期望的结果:

year  value  rank  value_relative
0  1990  100.0     2             0.5
1  1990  200.0     1             1.0
2  1992  300.0     2             0.75
3  1992  400.0     1             1.0
4  1992    NaN     3             NaN

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:58:26