如何在多索引中对排名列进行排序和添加?

时间:2017-05-18 16:27:51

标签: python pandas

我的pandas数据框看起来像这样(df3

df1 = pd.DataFrame({
    "period": [1, 2, 3, 4] * 4,
    "cat1": ["A"] * 8 + ["B"] * 8,
    "cat2": (["X"] * 4 + ["Y"] * 4) * 2,
    "amount": [100, 200, 300, 400, 110, 210, 310, 410, 120, 220, 320, 420, 130, 230, 330, 430],
    "total": [1000] * 16
})
df2 = df1.copy()
df2.amount = df2.amount + 1
df3 = pd.concat([df1, df2])

我想做的是

  • 根据cat1cat2period的值分组。
  • 过滤到每个组中具有最大amount值的行。
  • amount定义的组['cat1', 'cat2']内的结果数据框进行排序。(不是period)。
  • ['cat1', 'cat2']定义的每个组中添加累积百分比列。即,如果组中有4个值,则最高值将被分配0.25,第二个最高值将被分配0.5等。

我可以用

做前两部分
df4 = df3.groupby(['cat1', 'cat2', 'period']).agg({
    "amount": "max"
})

但现在df4['cat1', 'cat2', 'period']上有一个多索引,我不知道如何在多索引定义的组内进行排序,或者如何在这些组中添加累积计数。< / p>

我没有丢失多索引(我只是将这些数据插入到SQL表格中)但是我不知道如何做到这一点,如果它会是这样做很有效率。

我想要的结果是

cat1 cat2 period  amount  rank  percentage
A    X    4          401     1        0.25
A    X    3          301     2        0.50
A    X    2          201     3        0.75
A    X    1          101     4        1.00
A    Y    4          411     1        0.25
A    Y    3          311     2        0.50
A    Y    2          211     3        0.75
B    X    4          421     4        1.00
B    X    3          321     1        0.25
B    X    2          221     2        0.50
B    X    1          121     3        0.75
A    Y    1          111     4        1.00
B    Y    4          431     1        0.25
B    Y    3          331     2        0.50
B    Y    2          231     3        0.75
B    Y    1          131     4        1.00

(我实际上并不需要rank列,我只是为了清楚而将其留在那里。)

1 个答案:

答案 0 :(得分:1)

IIUC:

df4 = df3.groupby(['cat1', 'cat2', 'period']).agg({
    "amount": "max"
})
df4.reset_index(inplace=True)
df4 = df4.sort_values(by=['cat1','cat2','amount'],ascending=[True,True,False])
df4 = df4.assign(percentage=df4.groupby(['cat1','cat2'])['amount'].apply(lambda x: (x.notnull().cumsum()/x.size)))
print(df4)

输出:

   cat1 cat2  period  amount  percentage
3     A    X       4     401        0.25
2     A    X       3     301        0.50
1     A    X       2     201        0.75
0     A    X       1     101        1.00
7     A    Y       4     411        0.25
6     A    Y       3     311        0.50
5     A    Y       2     211        0.75
4     A    Y       1     111        1.00
11    B    X       4     421        0.25
10    B    X       3     321        0.50
9     B    X       2     221        0.75
8     B    X       1     121        1.00
15    B    Y       4     431        0.25
14    B    Y       3     331        0.50
13    B    Y       2     231        0.75
12    B    Y       1     131        1.00