在pandas中的多索引级别内按列排序

Dic*_*ter 23 python sorting pandas

我在下面的示例中有一个排序请求.

我需要reset_index(),然后sort()然后set_index()还是有一个光滑的方式来做到这一点?

l = [[1,'A',99],[1,'B',102],[1,'C',105],[1,'D',97],[2,'A',19],[2,'B',14],[2,'C',10],[2,'D',17]]
df = pd.DataFrame(l,columns = ['idx1','idx2','col1'])
df.set_index(['idx1','idx2'],inplace=True)

# assume data has been received like this...
print df

           col1
idx1 idx2      
1    A       99
     B      102
     C      105
     D       97
2    A       19
     B       14
     C       10
     D       17

# I'd like to sort descending on col1, partitioning within index level = 'idx2'

           col1
idx1 idx2      
1    C      105
     B      102
     A       99
     D       97

2    A       19
     D       17
     B       14
     C       10
Run Code Online (Sandbox Code Playgroud)

谢谢你的回答注意我稍微改变了数据:

l = [[1,'A',99],[1,'B',11],[1,'C',105],[1,'D',97],[2,'A',19],[2,'B',14],[2,'C',10],[2,'D',17]]
df = pd.DataFrame(l,columns = ['idx1','idx2','col1'])
df.set_index(['idx1','idx2'],inplace=True)
df = df.sort_index(by='col1', ascending=False)
Run Code Online (Sandbox Code Playgroud)

但输出是

idx1 idx2      
1    C      105
     A       99
     D       97
2    A       19
     D       17
     B       14
1    B       11
2    C       10
Run Code Online (Sandbox Code Playgroud)

我原本想要它

idx1 idx2      
1    C      105
     A       99
     D       97
     B       11

2    A       19
     D       17
     B       14
     C       10
Run Code Online (Sandbox Code Playgroud)

JAB*_*JAB 15

你可以使用sort_index:

 df.sort_index(by='col1', ascending=False)
Run Code Online (Sandbox Code Playgroud)

这输出:

             col1
idx1    idx2    
1       C    105
        B    102
        A    99
        D    97
2       A    19
        D    17
        B    14
        C    10
Run Code Online (Sandbox Code Playgroud)

  • 现在不推荐使用`by`参数的sort_index().这对这个答案有何影响? (3认同)
  • @ zthomas.nc我不认为这个答案适用于编辑过的数据.它适用于原始问题,但只有b/c idx = 1的所有col1值都大于idx = 2的所有col1值 (3认同)
  • 好的不用担心.我可以.reset_index(),然后对cols {idx1升序,col1降序}然后.set_index(['idx1','idx2'])进行常规排序 (2认同)

jez*_*ael 13

你需要DataFrame.reset_index,DataFrame.sort_valuesDataFrame.set_index::

l = [[1,'A',99],[1,'B',11],[1,'C',105],[1,'D',97],
     [2,'A',19],[2,'B',14],[2,'C',10],[2,'D',17]]
df = pd.DataFrame(l,columns = ['idx1','idx2','col1'])
df.set_index(['idx1','idx2'],inplace=True)
print (df)
           col1
idx1 idx2      
1    A       99
     B       11
     C      105
     D       97
2    A       19
     B       14
     C       10
     D       17

df = df.reset_index() \
       .sort_values(['idx1','col1'], ascending=[True,False]) \
       .set_index(['idx1','idx2'])
print (df)
           col1
idx1 idx2      
1    C      105
     A       99
     D       97
     B       11
2    A       19
     D       17
     B       14
     C       10
Run Code Online (Sandbox Code Playgroud)

编辑:

对于版本0.23.0,可以同时使用列和索引级别(但如果使用ascending=[True, False],现在可以使用bug ,因此可能在较新版本中):

df = df.sort_values(['idx1','col1'], ascending=[True,False])
print (df)

           col1
idx1 idx2      
1    C      105
     A       99
     D       97
     B       11
2    A       19
     D       17
     B       14
     C       10
Run Code Online (Sandbox Code Playgroud)


Kyl*_*yle 6

这首先按所需列进行排序,仅在idx1 MultiIndex级别上进行排序,并使用最新的pandas版本来弃用bykwarg.

df.sort_values('col1', ascending=False).sort_index(level='idx1', sort_remaining=False)
Run Code Online (Sandbox Code Playgroud)

输出:

             col1
idx1    idx2    
1       C    105
        B    102
        A    99
        D    97
2       A    19
        D    17
        B    14
        C    10
Run Code Online (Sandbox Code Playgroud)