【发布时间】:2018-05-11 16:43:09
【问题描述】:
我有一个未排序的数据框:
df
A B Moves
0 E1 E2 10
1 E1 E3 20
2 E1 E4 15
3 E2 E1 9
4 E2 E3 8
5 E2 E4 7
6 E3 E1 30
7 E3 E2 32
8 E3 E4 40
9 E4 E1 5
10 E4 E2 20
11 E4 E3 3
我想返回行B,直到它们的累积总和达到A 中B 的每个分组的总总数Moves 的某个最小百分比(我先取最高值)。
一旦达到 % 阈值,我将停止获取行(累积总和)。该过程必须是“贪婪的”,因为如果一行超过所需的百分比,它包括该行。
如果占总数的最小百分比是50%,那么我想先返回:
期望的输出
A B Moves
E1 E3 20
E1 E4 15
E2 E1 9
E2 E3 8
E3 E4 40
E3 E2 32
E4 E2 20
然后我想使用 df.groupby(...).apply(list) fromthis question 提取每个分组的行名
A Most_Moved
E1 [E3, E4]
E2 [E1, E3]
E3 [E4, E2]
E4 [E2]
我的尝试:
我可以在this 问题和this 问题中返回使用cumsum 订购的Total_Moves:
df.groupby(by=['A','B']).sum().groupby(level=[0]).cumsum()[::-1]
Moves
A B
E4 E3 28
E2 25
E1 5
E3 E4 102
E2 62
E1 30
E2 E4 24
E3 17
E1 9
E1 E4 45
E3 30
E2 10
另外,我可以返回每组的总移动数(总和):
df.groupby(by="A").sum()
Moves
A
E1 45
E2 24
E3 102
E4 28
从this question 和this question 我可以将每一行作为该类别总和的百分比返回:
df.groupby(by=["A"])["Moves"].apply(lambda x: 100 * x / float(x.sum()))
0 22.222222
1 44.444444
2 33.333333
3 37.500000
4 33.333333
5 29.166667
6 29.411765
7 31.372549
8 39.215686
9 17.857143
10 71.428571
11 10.714286
什么不起作用
但是,如果我将这些结合起来,它会评估整个行的百分比:
df.groupby(by=["A", "B"])["Moves"].agg({"Total_Moves":sum}).sort_values("Total_Moves", ascending=False).apply(lambda x: 100 * x / float(x.sum()))
Total_Moves
A B
E3 E4 20.100503
E2 16.080402
E1 15.075377
E1 E3 10.050251
E4 E2 10.050251
E1 E4 7.537688
E2 5.025126
E2 E1 4.522613
E3 4.020101
E4 3.517588
E4 E1 2.512563
E3 1.507538
这会评估整个数据框的百分比,而不是单个组内的百分比。
我只是不知道如何将这些拼凑起来得到我的输出。
任何帮助表示赞赏。
【问题讨论】:
标签: python pandas group-by sum percentage