【问题标题】:How to groupby a column and count the values on condition using python pandas?如何使用 python pandas 对列进行分组并计算条件值?
【发布时间】:2018-08-22 18:15:01
【问题描述】:

输入:

df=pd.DataFrame({
    'BusId':['abc1','abc2','abc3','abc1','abc2','abc4'],
    "Fair":[5,6,7,10,5,4]
})

需要按 BusId 分组,需要如下输出

输出:

BusId   Count of Fair>=5    Count of Fair>=10
abc1    2                         1
abc2    1                         0
abc3    1                         0
abc4    0                         0

感谢您的帮助。

【问题讨论】:

  • 它有效。请把它放在答案上

标签: python pandas


【解决方案1】:

在您的系列中使用 agg 和两个辅助函数来计算高于每个阈值的值。

但是,我在这里所做的系列聚合将在 pandas 的未来版本中被弃用。

df.groupby('BusId').Fair.agg({
    'gt5': lambda x: (x>=5).sum(),
    'gt10': lambda x: (x>=10).sum()
})

       gt5  gt10
BusId
abc1     2     1
abc2     2     0
abc3     1     0
abc4     0     0

你也可以去掉lambda的使用:

out = df.assign(gt5=df.Fair.ge(5), gt10=df.Fair.ge(10))
out.groupby('BusId').agg({'gt5': 'sum', 'gt10': 'sum'}).astype(int)

       gt5  gt10
BusId
abc1     2     1
abc2     2     0
abc3     1     0
abc4     0     0

第二种方法会稍微快一点:

%%timeit
df.groupby('BusId').Fair.agg({
    'gt5': lambda x: (x>=5).sum(),
    'gt10': lambda x: (x>=10).sum()
})

5.05 ms ± 69 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
out = df.assign(gt5=df.Fair.ge(5), gt10=df.Fair.ge(10))
out.groupby('BusId').agg({'gt5': 'sum', 'gt10': 'sum'}).astype(int)

3.76 ms ± 44.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

    【解决方案2】:

    您可以使用pd.cut 来避免对范围进行硬编码。只需剪切您的数据,然后应用cumsum

    binned_data = pd.cut(df.Fair, 
                         bins=[0, 5, 10, np.inf], 
                         labels=['>=0', '>=5', '>=10'], 
                         right=False)
    df = (pd.get_dummies(binned_data)
            .sort_index(axis=1, ascending=False)
            .cumsum(1)
            .groupby(df.BusId, sort=False)
            .sum()
            .iloc[:, 1::-1]))
    
    df
           >=5  >=10
    BusId           
    abc1     2     1
    abc2     2     0
    abc3     1     0
    abc4     0     0
    

    【讨论】:

      【解决方案3】:

      为避免聚合,您也可以改用apply。本质和user3483203的回答一样:

      df.groupby('BusId').apply(lambda x: pd.Series(
                     dict(five=(x.Fair >=  5).sum(),
                           ten=(x.Fair >= 10).sum())))
      # BusId              five              ten     
      # abc1                  2                1
      # abc2                  2                0
      # abc3                  1                0
      # abc4                  0                0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-13
        • 2017-02-22
        • 2015-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-16
        • 2021-07-28
        相关资源
        最近更新 更多