代码之家  ›  专栏  ›  技术社区  ›  Avi

python中是否有类似sql的行号选择?

  •  0
  • Avi  · 技术社区  · 6 年前

    我试图找到组中的值和,但问题是我只需要选择组中3个可能的最高值,然后对每个组的值求和。
    我有一个这样的数据框:

    group  amount
       x      12
       x     345
       x       3
       y       1
       y      45
       z      14
       x       4
       x      52
       y      54
       z      23
       z     235
       z      21
       y      57
       y       3
       z      87
    

    在sql中,我可以使用如下查询:

    select group,sum(amount)total from(select group,amount,row_number()over(partition by group order by amount desc)rownum from tbla)z 其中z.rownum介于1和3之间 分组

    在分组之前,我希望得到的结果是:

      group  amount
       x      12
       x     345
       y      45
       x      52
       y      54
       z      23
       z     235
       y      57
       z      87   
    

    根据这个结果我想得到每组的总和

    最终结果

        Group    Amount
        X         409
        Y         156
        Z         345
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Anton vBR    6 年前

    多亏了 @斯科特博顿 我看得更远,觉得我们可以 nth() 而不是 head() 利用 sum(level=0) .另一个选择是 set_index() 以前我用过两次groupby。不管怎样,按照速度的顺序,最快的是:

    dfout = (df.sort_values(by='amount', ascending=False)
             .groupby('group')
             .head(3)
             .set_index('group')
             .sum(level=0)
             .reset_index())
    

    dfout = (df.sort_values(by='amount', ascending=False)
             .groupby('group')
             .nth([0,1,2])
             .sum(level=0)
             .reset_index())
    

    dfout = (df.groupby('group')
             .apply(lambda x: x['amount'].sort_values(ascending=False).head(3).sum())
             .rename('amount')
             .reset_index())
    

    获取temp数据帧的两步方法,如问题所示:

    mid = df.sort_values(by='amount', ascending=False).groupby('group').head(3).sort_index()
    final = mid.set_index('group').sum(level=0)
    

    完整示例:

    import pandas as pd
    
    data = '''\
    group,amount
    x,12
    x,345
    x,3
    y,1
    y,45
    z,14
    x,4
    x,52
    y,54
    z,23
    z,235
    z,21
    y,57
    y,3
    z,87'''
    
    fileobj = pd.compat.StringIO(data)
    df = pd.read_csv(fileobj)
    
    dfout = (df.sort_values(by='amount', ascending=False)
             .groupby('group')
             .nth([0,1,2])
             .sum(level=0)
             .reset_index())
    
    print(dfout)
    

    返回:

      group  amount
    0     x     409
    1     y     156
    2     z     345