我有一个带有重复索引的pandas DataFrame。每个索引有3行,它们对应于一组项目。有两列,a
和b
。
df = pandas.DataFrame([{'i': b % 4, 'a': abs(b - 6) , 'b': b}
for b in range(12)]).set_index('i')
我想对DataFrame进行排序,以便:
a
的最低值相反。例如,在上面的df
中,前三项应该是索引为0
的项,因为这三行的最低a
值为2,并且所有其他组至少有一行a
值低于2.后三项可以是组3或组1,因为这两组中的最低a
值为1。最后一组项目应该是第2组,因为它有一个a
值为0的行。
b
按升序排序。期望的输出:
a b i 0 6 0 0 2 4 0 2 8 3 3 3 3 1 7 3 5 11 1 5 1 1 1 5 1 3 9 2 4 2 2 0 6 2 4 10
我一直在尝试这样的事情:
df.groupby('i')[['a']].transform(min).sort(['a', 'b'], ascending=[0, 1])
但是它给了我一个KeyError,如果我将i
作为列而不是索引,它只会走得那么远。
答案 0 :(得分:3)
您可以先按a
降序排序,然后对索引进行排序:
>>> df.sort(['a', 'b'], ascending=[False, True]).sort_index()
a b
i
0 6 0
0 2 4
0 2 8
1 5 1
1 3 9
1 1 5
2 4 2
2 4 10
2 0 6
3 5 11
3 3 3
3 1 7
答案 1 :(得分:3)
我看到的最直接的方法是将索引移动到列,并使用组min计算新列。
In [43]: df = df.reset_index()
In [45]: df['group_min'] = df.groupby('i')['a'].transform('min')
然后你可以按照你的条件排序:
In [49]: df.sort_values(['group_min', 'i', 'b'], ascending=[False, False, True])
Out[49]:
i a b group_min
0 0 6 0 2
4 0 2 4 2
8 0 2 8 2
3 3 3 3 1
7 3 1 7 1
11 3 5 11 1
1 1 5 1 1
5 1 1 5 1
9 1 3 9 1
2 2 4 2 0
6 2 0 6 0
10 2 4 10 0
要返回所需的帧,请删除跟踪变量并重置索引。
In [50]: df.sort_values(['group_min', 'i', 'b'], ascending=[False, False, True]).drop('group_min', axis=1).set_index('i')
Out[50]:
a b
i
0 6 0
0 2 4
0 2 8
3 3 3
3 1 7
3 5 11
1 5 1
1 1 5
1 3 9
2 4 2
2 0 6
2 4 10