如何在熊猫DataFrame中按行计算组中的空值

时间:2019-01-18 13:52:14

标签: pandas

根据本主题https://stackoverflow.com/questions/19384532/how-to-count-number-of-rows-per-group-and-other-statistics-in-pandas-group-by,我想再添加一个stat-在DataFrame中计数空值(又称NaN):

tdf = pd.DataFrame(columns = ['indicator', 'v1', 'v2', 'v3', 'v4'], 
                   data = [['A', '3', pd.np.nan, '4', pd.np.nan ],
                           ['A', '3', '4', '4', pd.np.nan ],
                           ['B', pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan],
                           ['B', '1', None, pd.np.nan, None ],
                           ['C', '9', '7', '4', '0']])

我想使用这样的东西:

tdf.groupby('indicator').agg({'indicator': ['count']})

,但增加了null计数器以将其放在单独的列中,例如:

tdf.groupby('indicator').agg({'indicator': ['count', 'isnull']})

现在,我得到了错误:AttributeError: Cannot access callable attribute 'isnull' of 'SeriesGroupBy' objects, try using the 'apply' method

如何在此处访问此pd.isnull()函数或将其用于某些功能?

预期输出为:

          indicator      nulls
              count      count
indicator          
A                 2          3
B                 2          7
C                 1          0

请注意,pd.np.nan的作用与None相同。

2 个答案:

答案 0 :(得分:1)

首先set_index并用sum计数检查所有缺失值,然后将countsum汇总:

df = tdf.set_index('indicator').isnull().sum(axis=1).groupby(level=0).agg(['count','sum'])
print (df)
           count  sum
indicator            
A              2    3
B              2    7
C              1    0

详细信息

print (tdf.set_index('indicator').isnull().sum(axis=1))
indicator
A    2
A    1
B    4
B    3
C    0
dtype: int64

另一种解决方案是对GroupBy.apply使用功能:

def func(x):
    a = len(x)
    b = x.isnull().values.sum()
    return pd.Series([a,b],index=['indicator count','nulls count'])

df = tdf.set_index('indicator').groupby('indicator').apply(func)
print (df)
           indicator count  nulls count
indicator                              
A                        2            3
B                        2            7
C                        1            0

答案 1 :(得分:0)

我发现自己的回答几乎令人满意:(缺点:太复杂了)。例如,在R中,我将在RowSums矩阵上使用is.na(df)。就是这样,但是不幸的是更多的编码。

def count_nulls_rowwise_by_group(tdf, group):
    cdf = pd.concat([tdf[group], pd.isnull(tdf).sum(axis=1).rename('nulls')], axis=1)
    return cdf.groupby(group).agg({group: 'count', 'nulls': 'sum'}).rename(index=str, columns={group: 'count'})

count_nulls_rowwise_by_group(tdf)

给予:

Out[387]: 
           count  nulls
indicator              
A              2      3
B              2      7
C              1      0