我有一个表,其中一些值属于索引,而另一些则属于重复值。在示例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中类别数量的成本。这样看起来就像
是否可以应用这种滚动功能?
答案 0 :(得分:3)
这是您可以做的事情:
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)
答案 1 :(得分:2)
我认为您需要对transform
和size
创建的每个组的sid
除法计数:
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