分组分类并计算要素中的缺失值

时间:2018-12-27 15:15:35

标签: python pandas dataframe group-by nan

我遇到了问题,即使我认为这很琐碎,也无法在Web或文档中找到任何解决方案。

我想做什么?

我有一个这样的数据框

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

我知道如何接收 nonnull 值-df.groupby['CLASS'].count()

NaN 值是否有相似之处?

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

3 个答案:

答案 0 :(得分:15)

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

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

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)

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

答案 1 :(得分:12)

您可以使用sumdf.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

输出:

    protected virtual string GetErrorPath()
    {
        return "~/Views/Shared/Error.cshtml";
    }

    public ViewResult ErrorView(string error, string errormessage)
    {
        ViewBag.ErrorType = error;
        ViewBag.ErrorMessage = errormessage;
        return View(GetErrorPath());
    }

答案 2 :(得分:7)

使用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