Groupby类并计算要素中的缺失值

Fli*_*xRo 18 python group-by dataframe pandas pandas-groupby

我有一个问题,我在网络或文档中找不到任何解决方案,即使我认为这是非常微不足道的.

我想做什么?

我有这样的数据帧

CLASS FEATURE1 FEATURE2 FEATURE3
  X      A       NaN      NaN
  X     NaN       A       NaN
  B      A        A        A
Run Code Online (Sandbox Code Playgroud)

我想按标签分组(CLASS)并显示每个功能中计算的NaN值的数量,使其看起来像这样.这样做的目的是大致了解缺失值如何分布在不同的类上.

CLASS FEATURE1 FEATURE2 FEATURE3
  X      1        1        2
  B      0        0        0
Run Code Online (Sandbox Code Playgroud)

我知道如何收到空的数量- 价值 -df.groupby['CLASS'].count()

NaN -Values 有类似的东西吗?

我试图从size()中减去count(),但它返回了一个填充了NaN值的无格式输出

cs9*_*s95 16

计算一个掩码isna,然后分组并找到总和:

df.drop('CLASS', 1).isna().groupby(df.CLASS, sort=False).sum().reset_index()

  CLASS  FEATURE1  FEATURE2  FEATURE3
0     X       1.0       1.0       2.0
1     B       0.0       0.0       0.0
Run Code Online (Sandbox Code Playgroud)

另一种选择是减去sizecount使用rsub沿0 索引对准减法轴:

df.groupby('CLASS').count().rsub(df.groupby('CLASS').size(), axis=0)
Run Code Online (Sandbox Code Playgroud)

要么,

g = df.groupby('CLASS')
g.count().rsub(g.size(), axis=0)
Run Code Online (Sandbox Code Playgroud)

       FEATURE1  FEATURE2  FEATURE3
CLASS                              
B             0         0         0
X             1         1         2
Run Code Online (Sandbox Code Playgroud)

有很多好的答案,所以这里有一些timeits供你细读:

df_ = df
df = pd.concat([df_] * 10000)

%timeit df.drop('CLASS', 1).isna().groupby(df.CLASS, sort=False).sum()
%timeit df.set_index('CLASS').isna().sum(level=0)    
%%timeit
g = df.groupby('CLASS')
g.count().rsub(g.size(), axis=0)

11.8 ms ± 108 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.47 ms ± 379 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
6.54 ms ± 81.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)

实际性能取决于您的数据和设置,因此您的里程可能会有所不同.


Sco*_*ton 15

你可以使用set_indexsum:

df.set_index('CLASS').isna().sum(level=0)
Run Code Online (Sandbox Code Playgroud)

输出:

       FEATURE1  FEATURE2  FEATURE3
CLASS                              
X           1.0       1.0       2.0
B           0.0       0.0       0.0
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 7

使用之间的差异countsize

g=df.groupby('CLASS')

-g.count().sub(g.size(),0)

          FEATURE1  FEATURE2  FEATURE3
CLASS                              
B             0         0         0
X             1         1         2
Run Code Online (Sandbox Code Playgroud)

我们可以将这个问题转换为更通用的问题,如何NaN用for循环计算数据帧中的数量

pd.DataFrame({x: y.isna().sum()for x , y in g }).T.drop('CLASS',1)
Out[468]: 
   FEATURE1  FEATURE2  FEATURE3
B         0         0         0
X         1         1         2
Run Code Online (Sandbox Code Playgroud)