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

如何通过列除法为Pandas分组结果新增average列

问题:为分组统计后的DataFrame添加平均值列

我创建了一个按年份分组的DataFrame,用于统计至少有1个非空值的唯一州数量,以及非空值的总数。但在新增一列(用非空值总数除以唯一州数量)时遇到了困难。

示例数据

nan = float('nan')
df = pd.DataFrame({
    'year': [2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2019, 2019],
    'state': [1, 2, 3, 1, 2, 1, 2, 3, 4, 5],
    'var1': [nan, 1.0, nan, 1.0, nan, nan, 1.0, nan, 2.0, 2.0],
    'var2': [2.0, 1.0, nan, 2.0, 1.0, nan, 1.0, nan, 1.0, nan],
})

当前代码

import numpy as np

c = df.groupby(['year', 'state']).count()
res = c.groupby('year').agg([np.count_nonzero, sum])

当前输出

var1                    var2
        count_nonzero   sum     count_nonzero   sum
year                
2018    2               2       2               4
2019    3               3       2               2

期望输出

var1                                    var2
        count_nonzero   sum     average         count_nonzero   sum    average
year                
2018    2               2       1               2               4      2
2019    3               3       1               2               2      1

解决方案

方法一:直接计算并插入平均值列

利用原结果的多层列结构,分别对var1和var2计算sum / count_nonzero,再将结果作为新层级列添加,最后调整列顺序匹配期望输出:

import numpy as np
import pandas as pd

nan = float('nan')
df = pd.DataFrame({
    'year': [2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2019, 2019],
    'state': [1, 2, 3, 1, 2, 1, 2, 3, 4, 5],
    'var1': [nan, 1.0, nan, 1.0, nan, nan, 1.0, nan, 2.0, 2.0],
    'var2': [2.0, 1.0, nan, 2.0, 1.0, nan, 1.0, nan, 1.0, nan],
})

c = df.groupby(['year', 'state']).count()
res = c.groupby('year').agg([np.count_nonzero, sum])

# 计算并添加var1的平均值列
res[('var1', 'average')] = res[('var1', 'sum')] / res[('var1', 'count_nonzero')]
# 计算并添加var2的平均值列
res[('var2', 'average')] = res[('var2', 'sum')] / res[('var2', 'count_nonzero')]

# 调整列顺序,匹配期望输出的结构
res = res.reindex(columns=['var1', 'var2'], level=0)
res = res.reindex(columns=['count_nonzero', 'sum', 'average'], level=1)

print(res)

方法二:自定义聚合函数

通过自定义聚合逻辑,在分组时直接生成包含平均值的统计结果,适合需要扩展更多统计项的场景:

import numpy as np
import pandas as pd

nan = float('nan')
df = pd.DataFrame({
    'year': [2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2019, 2019],
    'state': [1, 2, 3, 1, 2, 1, 2, 3, 4, 5],
    'var1': [nan, 1.0, nan, 1.0, nan, nan, 1.0, nan, 2.0, 2.0],
    'var2': [2.0, 1.0, nan, 2.0, 1.0, nan, 1.0, nan, 1.0, nan],
})

def agg_stats(x):
    count = np.count_nonzero(x)
    total = x.sum()
    # 避免除数为0的情况,返回nan
    avg = total / count if count != 0 else np.nan
    return pd.Series([count, total, avg], index=['count_nonzero', 'sum', 'average'])

# 先按year+state分组统计,再按year聚合生成完整统计项
c = df.groupby(['year', 'state']).count()
res = c.groupby('year').apply(lambda group: group.apply(agg_stats))

print(res)

两种方法都能得到你期望的输出,方法一更直接高效,方法二更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 01:03:11