【问题标题】:Perform COUNTIF with GROUP BY in Pandas - Python 3.x在 Pandas 中使用 GROUP BY 执行 COUNTIF - Python 3.x
【发布时间】:2019-10-24 04:10:41
【问题描述】:

我有一个数据框,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 |

除了我有大约 13,000 个特征,并且只关心某个子集(比如 foo1、foo2、foo3、foo4 和 foo5)

我的df的形状是: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,但这是为所有列创建类似计算的方法,我只关心特定的五个(foo1foo2foo3foo4, foo5)

如何使用 python pandas 编写解决方案以达到预期结果?

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    如果我理解正确,首先set_indexrating,然后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
    

    【讨论】:

    • 谢谢亨利。好建议。不幸的是,我不知道其他评分来自哪里(我只有两个),而且我也不是在寻找总和......我正在寻找非 0 项目的计数。
    • sum on boolean True/False 是一个计数。
    • 我如何指定只对列 foo1foo2foo3foo4foo4foo5 执行此功能,而不是我拥有的所有 ~14K 列?
    • 您可以使用cols=df.columns[1:6] 来选择要在其上执行此操作的列并在这些列上应用 lambda。检查我的答案。
    • df[["foo1","foo2"...]].groupby(...)`.
    【解决方案2】:

    你可以这样做

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-07
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多