代码之家  ›  专栏  ›  技术社区  ›  artemis Roberto

在pandas-python 3.x中使用group by执行countif

  •  0
  • artemis Roberto  · 技术社区  · 5 年前

    我有一个数据框, df ,如下所示:

    |    | rating |  foo1 | foo2 |  foo3 | foo4 |  foo5 | 
    |:--:|:------:|:-----:|:----:|:-----:|:----:|:-----:|
    |  1 |    2   |   0   |   0  |  0.98 |   0  |  0.7  |
    |  2 |    2   |   0   |   0  |   0   |  0.3 | 0.007 |
    |  3 |    2   |   0   |   0  |   0   |   0  |   0   |
    |  4 |    4   |  0.1  | 0.99 |   0   |   0  | 0.005 |
    |  5 |    4   |   0   |   0  |   0   |   0  |  0.01 |
    |  6 |    2   |   0   |   0  |  0.66 |   0  |  0.27 |
    |  7 |    4   |   0   | 0.92 |  0.32 |   0  |  0.11 |
    |  8 |    2   | 0.003 |   0  | 0.073 |   0  | 0.218 |
    |  9 |    4   |   0   |   0  |   0   |   0  | 0.004 |
    | 10 |    4   |   0   |   0  |   0   |   0  | 0.001 |
    

    除了我有13000个特性,并且只关心某个子集(比如foo1、foo2、foo3、foo4和foo5)

    我的形状 数据框 是: 2000 rows x 13984 columns

    我需要做的是计算每列的非零个数,并按评级对其进行分组,以希望产生如下结果:

    |   | foo1 | foo2 | foo3 | foo4 | foo5 |
    |:-:|:----:|:----:|:----:|:----:|:----:|
    | 2 |   1  |   0  |   3  |   1  |   4  |
    | 4 |   1  |   2  |   1  |   0  |   5  |
    

    我知道在SQL中,我可以做如下事情:

    SELECT
            rating,
            SUM(CASE WHEN foo1 != 0 THEN 1 ELSE 0 END) as foo1,
            SUM(CASE WHEN foo2 != 0 THEN 1 ELSE 0 END) as foo2,
            SUM(CASE WHEN foo3 != 0 THEN 1 ELSE 0 END) as foo3,
            SUM(CASE WHEN foo4 != 0 THEN 1 ELSE 0 END) as foo4,
            SUM(CASE WHEN foo5 != 0 THEN 1 ELSE 0 END) as foo5
    
    FROM
            df
    
    GROUP BY
            rating
    

    我发现了 this Stack Overflow post 但这是如何为 所有列 ,我只关心具体的五个( foo1 我是说, foo2 ,请 foo3 ,请 foo4 我是说, foo5 )

    如何使用python pandas编写解决方案以获得所需的结果?

    2 回复  |  直到 5 年前
        1
  •  3
  •   Henry Yik    5 年前

    如果我理解正确,首先 set_index rating ,然后 groupby :

    import numpy as np
    import pandas as pd
    
    np.random.seed(500)
    
    e = {"rating":np.random.choice([2,4],100),
         "foo1": np.random.randint(0,2,100),
         "foo2": np.random.randint(0,2,100),
         "foo3": np.random.randint(0,2,100),
         "foo4": np.random.randint(0,2,100)}
    
    df = pd.DataFrame(e)
    df = df.set_index("rating")
    print (df.groupby(df.index).apply(lambda x: x.ne(0).sum()))
    
    #
            foo1  foo2  foo3  foo4
    rating                        
    2         21    21    24    19
    4         32    26    24    30
    
        2
  •  0
  •   moys    5 年前

    你可以这样做

    cols=df.columns[1:6]
    df.groupby('rating')[cols].apply(lambda x: x.ne(0).sum()).reset_index()
    

    #

    rating  foo1    foo2    foo3    foo4    foo5
    0   2   1   0   3   1   4
    1   4   1   2   1   0   5