pandas Groupby类和计算要素中的缺失值

aoyhnmkz  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(119)

我有一个这样的相框

CLASS FEATURE1 FEATURE2 FEATURE3
  X      A       NaN      NaN
  X     NaN       A       NaN
  B      A        A        A

字符串
我想按标签CLASS分组,并显示每个特征中计数的NaN值的数量,使其看起来像这样。目的是大致了解缺失值如何分布在不同的类中。

CLASS FEATURE1 FEATURE2 FEATURE3
  X      1        1        2
  B      0        0        0


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

  • NaN* 值是否有类似的情况?

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

zengzsys

zengzsys1#

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

字符串
另一种选择是使用rsub沿沿着第0轴从count中减去size,以进行索引对齐减法:

df.groupby('CLASS').count().rsub(df.groupby('CLASS').size(), axis=0)


或者,

g = df.groupby('CLASS')
g.count().rsub(g.size(), axis=0)

FEATURE1  FEATURE2  FEATURE3
CLASS                              
B             0         0         0
X             1         1         2


有很多很好的答案,所以这里有一些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)


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

odopli94

odopli942#

由于未来警告而更新:
未来警告:不建议在DataFrame和Series聚合中使用level关键字,并且将在将来的版本中删除。请改用groupby。df.sum(level=1)应使用df.groupby(level=1).sum()。
df.set_index('CLASS').isna().sum(level=0)

df.set_index('CLASS').isna().groupby(level=0).sum()

字符串
可以使用set_indexsum

# Will be deprecated soon.. do not use. You should use above statement instead.
df.set_index('CLASS').isna().sum(level=0)


输出量:

FEATURE1  FEATURE2  FEATURE3
CLASS                              
X           1.0       1.0       2.0
B           0.0       0.0       0.0

ifmq2ha2

ifmq2ha23#

使用countsize之间的差异

g=df.groupby('CLASS')

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

          FEATURE1  FEATURE2  FEATURE3
CLASS                              
B             0         0         0
X             1         1         2

字符串
我们可以将这个问题转换为更一般的问题,如何在for循环中计算NaN的数量

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

hgqdbh6s

hgqdbh6s4#

不使用groupby的解决方案可以是使用pivot_table和自定义聚合函数。
这个解决方案可能比其他解决方案更清楚地传达意图(至少对我来说)。
生成嵌套框架:

import pandas as pd
import numpy as np
df = pd.DataFrame({"CLASS":["X","X","B"],
                    "FEATURE1":["A", np.nan, "A",],
                    "FEATURE2":[np.nan,"A",  "A",],
                    "FEATURE3":[np.nan,np.nan,  "A",]
                  }
                 )

字符串
生成透视表:

df.pivot_table(index="CLASS", 
               values=["FEATURE1","FEATURE2","FEATURE3"], 
               aggfunc= lambda x: x.isna().sum())
Out [2]:
       FEATURE1  FEATURE2  FEATURE3
CLASS                              
B             0         0         0
X             1         1         2

性能:

此外,在性能方面,该解决方案似乎是最快的。


的数据

sbtkgmzw

sbtkgmzw5#

另一个解决方案(主要是为了好玩):

df.assign(
    **{col: df[col].isna() for col in df.columns if col not in "CLASS"},
).groupby("CLASS").sum()

字符串

相关问题