Sorting by a combination of columns and index levels
我一直在努力,我怀疑有更好的方法。如何按索引级别名称'idx_0',level = 0和按列','value_1'降序排序以下数据帧,以便列'MyName'读取垂直'SCOTTBOSTON'。
import pandas as pd
import numpy as np
df = pd.DataFrame({'idx_0':[2]*6+[1]*5,
'idx_1':[6,4,2,10,18,5,11,1,7,9,3],
'value_1':np.arange(11,0,-1),
'MyName':list('BOSTONSCOTT')})
df = df.set_index(['idx_0','idx_1'])
df
输出:
MyName value_1
idx_0 idx_1
2 6 B 11
4 O 10
2 S 9
10 T 8
18 O 7
5 N 6
1 11 S 5
1 C 4
7 O 3
9 T 2
3 T 1
df.sort_values(['value_1'], ascending=False)\
.reindex(sorted(df.index.get_level_values(0).unique()), level=0)
我怀疑没有重置索引的方法更简单
MyName value_1
idx_0 idx_1
1 11 S 5
1 C 4
7 O 3
9 T 2
3 T 1
2 6 B 11
4 O 10
2 S 9
10 T 8
18 O 7
5 N 6
df.sort_values('value_1', ascending=False).sort_index(level=0)
首先按值排序,然后对索引级别= 0进行排序,但也会对level = 1进行排序。
MyName value_1
idx_0 idx_1
1 1 C 4
3 T 1
7 O 3
9 T 2
11 S 5
2 2 S 9
4 O 10
5 N 6
6 B 11
10 T 8
18 O 7
df.sort_index(level=0).sort_values('value_1', ascending=False)
按索引级别= 0排序,然后按值排序,但索引= 0再次混淆。
MyName value_1
idx_0 idx_1
2 6 B 11
4 O 10
2 S 9
10 T 8
18 O 7
5 N 6
1 11 S 5
1 C 4
7 O 3
9 T 2
3 T 1
答案 0 :(得分:1)
这是我丑陋的选择:
In [139]: (df.assign(x=df.index.get_level_values(0) * \
10**np.ceil(np.log10(df.value_1.max()))-df.value_1)
.sort_values('x')
.drop('x',1))
Out[139]:
MyName value_1
idx_0 idx_1
1 11 S 5
1 C 4
7 O 3
9 T 2
3 T 1
2 6 B 11
4 O 10
2 S 9
10 T 8
18 O 7
5 N 6
一些解释:
In [140]: np.ceil(np.log10(df.value_1.max()))
Out[140]: 2.0
In [141]: df.assign(x=df.index.get_level_values(0)*10**np.ceil(np.log10(df.value_1.max()))-df.value_1)
Out[141]:
MyName value_1 x
idx_0 idx_1
2 6 B 11 189.0
4 O 10 190.0
2 S 9 191.0
10 T 8 192.0
18 O 7 193.0
5 N 6 194.0
1 11 S 5 95.0
1 C 4 96.0
7 O 3 97.0
9 T 2 98.0
3 T 1 99.0
另一种选择是添加idx_0
排序,然后按value_1
排序并删除其他列:
In [142]: (df.assign(x=df.index.get_level_values(0)).sort_values(['x', 'value_1'], ascending=[1,0])
.drop('x',1))
Out[142]:
MyName value_1
idx_0 idx_1
1 11 S 5
1 C 4
7 O 3
9 T 2
3 T 1
2 6 B 11
4 O 10
2 S 9
10 T 8
18 O 7
5 N 6
答案 1 :(得分:1)
以下是一些可满足您需求的潜在解决方案:
方式-1:强>
(df.sort_values('value_1', ascending=False)
.sort_index(level=[0], ascending=[True]))
方式-2:强>
(df.set_index('value_1', append=True)
.sort_index(level=[0,2], ascending=[True,False])
.reset_index('value_1'))
在pandas 0.22.0,Python 3.6.4
上测试答案 2 :(得分:0)
Sorting by a combination of columns and index levels
df.sort_values(by=['idx_0','value_1'], ascending=[True,False])
输出:
value_1 MyName
idx_0 idx_1
1 11 5 S
1 4 C
7 3 O
9 2 T
3 1 T
2 6 11 B
4 10 O
2 9 S
10 8 T
18 7 O
5 6 N
有趣的是,@ jxc指出了一个我认为应该有效的解决方案,并且 几乎 就像我的第一次失败一样。
df.sort_values('value_1', ascending=False)\
.sort_index(level=0, ascending=[True])
传递ascending
作为列表,使上述语句作为例外工作。我认为在大熊猫中传递一个标量值并且一个列表应该是相同的。但是,在这种情况下,它似乎不起作用。
我会提交错误报告。