如何基于station和time分组计算指定组别组合的均值?
问题
需要在Pandas DataFrame中,按station和time分组后,计算每组内A&B、B&C、A&C这三组组合的value列均值,同时保留整体均值。目前已实现整体均值计算,但计算指定组别组合均值时返回NaN值。
数据集示例
station group groupA groupB groupC value time 1 A A nan nan 4 30 1 B nan B nan 7 30 1 C nan nan C 6 30 2 A A nan nan 5 30 2 B nan B nan 3 30 2 C nan nan C 1 30 3 A A nan nan 2 30 3 B nan B nan 3 30 3 C nan nan C 4 30 ....
已实现的整体均值代码
# 计算每个station+time组的整体均值,此代码正常运行 df['mean_allstations'] = df.groupby(['station','time'])['value'].transform('mean')
尝试失败的代码(返回NaN)
# 尝试计算每个station+time组内A和B的均值,但返回全NaN列 df['mean_AB'] = df.groupby(['station','time', 'groupA', 'groupB'])['value'].transform('mean')
期望输出
station group groupA groupB groupC value time meanAB meanAC meanBC ALLme 1 A A nan nan 4 30 5.5 5 6.5 5.6 1 B nan B nan 7 30 5.5 5 6.5 5.6 1 C nan nan C 6 30 5.5 5 6.5 5.6 2 A A nan nan 5 30 4 3 2 3 2 B nan B nan 3 30 4 3 2 3 2 C nan nan C 1 30 4 3 2 3 3 A A nan nan 2 30 2.5 3 3.5 3 3 B nan B nan 3 30 2.5 3 3.5 3 3 C nan nan C 4 30 2.5 3 3.5 3
解决方案
问题原因
之前的代码返回NaN,是因为groupA、groupB列存在大量缺失值,按这些列分组后,每个子组仅包含单一行数据(比如A组的行只有groupA有值,其余列均为NaN),无法有效计算均值,最终返回NaN。
实现方法
核心逻辑是在每个station+time分组内,筛选出目标group的行计算均值,再将结果广播到分组内所有行,以下提供两种可行方案:
方案1:自定义函数+groupby.apply
def calculate_group_means(group): # 计算A&B组合均值:筛选group为A、B的行 group['meanAB'] = group[group['group'].isin(['A', 'B'])]['value'].mean() # 计算A&C组合均值:筛选group为A、C的行 group['meanAC'] = group[group['group'].isin(['A', 'C'])]['value'].mean() # 计算B&C组合均值:筛选group为B、C的行 group['meanBC'] = group[group['group'].isin(['B', 'C'])]['value'].mean() # 整体均值 group['ALLme'] = group['value'].mean() return group # 应用到每个station+time分组 df = df.groupby(['station', 'time']).apply(calculate_group_means).reset_index(drop=True)
方案2:transform结合lambda(更简洁)
# 计算A&B均值 df['meanAB'] = df.groupby(['station','time'])['value'].transform( lambda x: x[df.loc[x.index, 'group'].isin(['A','B'])].mean() ) # 计算A&C均值 df['meanAC'] = df.groupby(['station','time'])['value'].transform( lambda x: x[df.loc[x.index, 'group'].isin(['A','C'])].mean() ) # 计算B&C均值 df['meanBC'] = df.groupby(['station','time'])['value'].transform( lambda x: x[df.loc[x.index, 'group'].isin(['B','C'])].mean() ) # 整体均值 df['ALLme'] = df.groupby(['station','time'])['value'].transform('mean')
效果验证
两种方案均能得到符合期望的输出,解决了原代码返回NaN的问题,同时保留了整体均值的计算逻辑。
内容的提问来源于stack exchange,提问作者cl_gre
相关产品推荐
相关产品推荐

