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

时间:2015-02-06 17:22:39

标签: python pandas sorting

我在下面的每个例子中都有一个排序请求。

我需要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

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

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)

然而输出是

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

我原本希望它是

idx1 idx2      
1    C      105
     A       99
     D       97
     B       11

2    A       19
     D       17
     B       14
     C       10

4 个答案:

答案 0 :(得分:13)

您可以使用sort_index

 df.sort_index(by='col1', ascending=False)

输出:

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

答案 1 :(得分:11)

您需要DataFrame.reset_indexDataFrame.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

编辑:

对于版本0.23.0,可以使用columns and index levels together(但现在如果使用ascending=[True, False]则有错误,所以可能在较新的版本中):

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

答案 2 :(得分:6)

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

df.sort_values('col1', ascending=False).sort_index(level='idx1', sort_remaining=False)

输出:

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

答案 3 :(得分:0)

使用groupby(已经存在的索引)和应用的另一种方法:

df.groupby(level=[0]).apply(lambda x:x.groupby(level=[1]).sum().sort_values('col1',ascending=False))

输出:

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