【问题标题】:Groupby class and count missing values in features分组分类并计算特征中的缺失值
【发布时间】:2019-05-25 14:38:27
【问题描述】:

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

我想做什么?

我有一个这样的数据框

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-Values 的数量 - df.groupby['CLASS'].count()

NaN-Values 有类似的东西吗?

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

【问题讨论】:

    标签: python pandas dataframe group-by pandas-groupby


    【解决方案1】:

    由于未来警告而更新:

    FutureWarning:使用关卡 DataFrame 和 Series 聚合中的关键字已弃用,并将 在未来的版本中删除。请改用 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 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
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        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 沿第 0th 轴从 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)
        

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

        【讨论】:

        • 我想更好地理解第一个代码。您能否解释一下 df.drop('CLASS', 1) 在这种情况下的作用?谢谢
        • .groupby(df.CLASS) 哇,真棒!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-08
        • 1970-01-01
        • 2014-10-04
        • 2019-08-10
        • 2020-03-27
        相关资源
        最近更新 更多