【问题标题】:Is there any row number alternative like SQL in python?python中是否有任何行号替代方法,如SQL?
【发布时间】:2018-07-08 21:31:54
【问题描述】:

我试图找到组中的值的总和,但问题是我只需要选择组中的 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

IN 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

【问题讨论】:

    标签: pandas python-3.6 pandas-groupby


    【解决方案1】:

    感谢@ScottBoston,我进一步研究并认为我们可以使用nth() 而不是head() 来使用sum(level=0)。另一种选择是 set_index() before 而不是我使用 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())
    

    一种两步方法来获取您的临时数据框,如问题所示:

    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
    

    【讨论】:

    • @ScottBoston 我想通了。 groupby 上的 head() 返回一个没有 groupby 对象作为索引的数据帧。所以我们错过了我们应该set_index('group') 的事实。另一种选择是使用 nth。谢谢你让我好奇:)
    • 感谢@Anton vBR 和 Scott Boston 的时间和提供信息。我只是想知道 reset index 会做什么,并且我查看了排序与我所拥有的不同的结果。那是使用 reset_index 吗?以确保之前的行顺序保持不变。
    • @Avi 你想要中间数据框吗?然后你可以这样做,例如:df.sort_values(by='amount', ascending=False).groupby('group').head(3).sort_index()。最后的reset_index() 只是将组列从索引移到列,因为它看起来像您可能想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 2011-04-21
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多