【问题标题】:How to equally reduce value after grouping?分组后如何平均减值?
【发布时间】:2019-05-18 18:51:31
【问题描述】:

我有一个表,其中一些值属于索引,而另一些属于重复值。例如sid 是索引,成本归属于 sid,但一个 sid 可以包含许多事务,甚至多个事务可以包含多个类别。

df = pd.DataFrame([
    [1, 100, 1, 'A', 1, 50, 2],
    [1, 100, 2, 'A', 1, 50, 1],
    [1, 100, 2, 'B', 2, 100, 1],
    [1, 100, 2, 'C', 3, 50, 1],
    [2, 200, 3, 'D', 4, 500, 1],
    [2, 200, 4, 'C', 2, 100, 1],
    [3, 200, 5, 'B', 2, 100, 1],
    [3, 200, 5, 'A', 1, 50, 1],
    [3, 200, 5, 'A', 3, 50, 1]
], columns=['sid', 'costs', 'transaction_id', 'category', 'sku', 'price', 'quantity'])

df['revenue'] = df['price'] * df['quantity']

因此,如果查看 sid 级别,我需要获取成本的第一个值和收入的总和。这就是它应该的样子。总成本 - 500,总收入 - 1100。

df.groupby('sid').agg({'costs': 'min', 'revenue':'sum'}).pivot_table(index='sid', margins=True, aggfunc='sum')  

但我想按类别分解 sid。我可以这样做。

df.groupby(['sid', 'category']).agg({'costs': 'min', 'revenue':'sum'}).pivot_table(index=['sid', 'category'], aggfunc='sum', margins=True)

我的问题是每一行的成本都是重复的。成本总和为 1100,这是不正确的。我想同样降低每个 sid 中​​类别数量的成本。所以它看起来像

是否可以应用这种滚动功能?

【问题讨论】:

  • 我对你的问题有点困惑。您如何获得 sid 1 和 A 类 33.34 的成本?
  • @amanbirs 这是我想要实现的示例。是的,我知道这在成本方面可能没有意义,因为这不是在某些类别上花费的价值,但现在我有兴趣通过 pandas 实现这样的结果。如何解释是另一个问题

标签: python pandas pivot-table pandas-groupby


【解决方案1】:

我认为您需要将sid 的数量除以transformsize 创建的每个组:

df = df.groupby(['sid', 'category']).agg({'costs': 'min', 'revenue':'sum'})
df['costs'] = df['costs'].div(df.groupby('sid')['costs'].transform('size'))
df = df.pivot_table(index=['sid', 'category'], aggfunc='sum', margins=True)
print (df)
                   costs  revenue
sid category                     
1   A          33.333333      150
    B          33.333333      100
    C          33.333333       50
2   C         100.000000      100
    D         100.000000      500
3   A         100.000000      100
    B         100.000000      100
All           500.000000     1100

【讨论】:

    【解决方案2】:

    你可以这样做:

    g = df.groupby(['sid', 'category']).agg({'revenue':'sum', 'costs': 'min'})
    div = df.groupby(['sid'])['category'].nunique()
    g['costs'] = g['costs']/div
    
                    revenue     costs
    sid category                     
    1   A             150   33.333333
        B             100   33.333333
        C              50   33.333333
    2   C             100  100.000000
        D             500  100.000000
    3   A             100  100.000000
        B             100  100.000000
    

    对于最后一行,包括两列的sum,只需在末尾再次添加:

    g.pivot_table(index=['sid', 'category'], aggfunc='sum', margins=True)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多