按多列和重复索引对pandas DataFrame进行排序

时间:2015-10-18 01:47:26

标签: python pandas

我有一个带有重复索引的pandas DataFrame。每个索引有3行,它们对应于一组项目。有两列,ab

df = pandas.DataFrame([{'i': b % 4, 'a': abs(b - 6) , 'b': b}
                       for b in range(12)]).set_index('i')

我想对DataFrame进行排序,以便:

  1. 具有相同索引的所有行都是相邻的。 (所有小组都在一起)
  2. 这些组的顺序与组内a的最低值相反。
  3. 例如,在上面的df中,前三项应该是索引为0的项,因为这三行的最低a值为2,并且所有其他组至少有一行a值低于2.后三项可以是组3或组1,因为这两组中的最低a值为1。最后一组项目应该是第2组,因为它有一个a值为0的行。

    1. 在每个组中,项目按b按升序排序。
    2. 期望的输出:

          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作为列而不是索引,它只会走得那么远。

2 个答案:

答案 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