如何在Pandas中按聚合级别统计列非空值?解决agg计数错误
解决按聚合级别统计非空值的问题
嘿,我来帮你搞清楚这个问题~
首先,咱们先看你的示例数据:
import pandas as pd import numpy as np df = pd.DataFrame({'agr' : [1,1,1], 'col1' : [1, np.nan, np.nan], 'col2' : [np.nan, 2, 3] })
你说用df.agg({'col1' : [np.sum, np.count_nonzero], 'col2' : [ np.sum, np.count_nonzero]})得到了3、3,但实际需要1、2,这里的核心问题主要有两个:
问题出在哪?
- 缺少分组操作:你的需求是「按聚合级别(也就是
agr列)统计」,但直接调用df.agg()是对整个DataFrame的列做全局统计,而不是按agr分组后统计。不过你的示例里agr全是1,全局统计和分组统计结果应该一致,那大概率是你误写了统计函数? - 函数理解偏差:如果真的得到了3,你可能不小心用了
len()这类统计总行数的函数。其实np.count_nonzero本身会排除NaN(因为NaN不属于非零值),在你的示例里col1的count_nonzero结果应该是1,col2是2,和你需要的结果一致。
正确的解决办法
如果你需要按agr分组统计每组内各列的非空值数量和求和,一定要先做groupby,然后再用agg。这里更推荐用Pandas内置的'sum'和'count'别名,比np.sum和np.count_nonzero更贴合Pandas的Series处理逻辑:
# 按agr分组后聚合 result = df.groupby('agr').agg({ 'col1': ['sum', 'count'], # count专门统计非空值数量 'col2': ['sum', 'count'] }) print(result)
运行后得到的结果是:
col1 col2 sum count sum count agr 1 1.0 1 5.0 2
正好符合你需要的col1非空数1,col2非空数2的要求。
如果你一定要用numpy的函数,也可以这么写:
result = df.groupby('agr').agg({ 'col1': [np.sum, lambda x: np.count_nonzero(x.notna())], 'col2': [np.sum, lambda x: np.count_nonzero(x.notna())] })
这里用x.notna()先把非空值转成布尔值,再用np.count_nonzero统计,结果和上面一致。
小提醒
Pandas的count()方法是专门为Series设计的,用来统计非空值的数量,比np.count_nonzero更直观,也能避免因为NaN的类型问题导致的意外结果,所以优先推荐使用。
内容的提问来源于stack exchange,提问作者Rocketq
相关产品推荐
相关产品推荐

