在 pandas 中的多索引级别内按列排序
Sort by column within multi index level in 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
谢谢您的回答
注意我稍微更改了数据:
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
你可以使用 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
你需要 DataFrame.reset_index
, DataFrame.sort_values
and DataFrame.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
这首先按所需列排序,仅在 idx1 MultiIndex 级别上求助,并在最新的 pandas 版本中工作,该版本弃用了 by
kwarg。
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
另一种使用 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
我对下面的示例有一个排序请求。
我是否需要 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
你可以使用 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
你需要 DataFrame.reset_index
, DataFrame.sort_values
and DataFrame.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
这首先按所需列排序,仅在 idx1 MultiIndex 级别上求助,并在最新的 pandas 版本中工作,该版本弃用了 by
kwarg。
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
另一种使用 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