我有一个数据帧df
,如下所示:
a b
id no name
T01 101 foo 1 $10
T32 102 bar 2 $30
T10 103 baz 4 $25
其中索引为CCD_ 2。我有另一个数据帧df2
,具有我希望的索引顺序
no
0 103
1 101
2 102
我需要数据帧是
a b
id no name
T10 103 baz 4 $25
T01 101 foo 1 $10
T32 102 bar 2 $30
我见过使用df.loc[df2.no.values]
和df.reindex(df2.no)
,但由于我有多索引的dataFrame,它似乎不起的作用
我应该用什么来按照df2
中的顺序对密钥no
中的df
进行排序?
使用reset_index
、reindex
和最后一个set_index
:的一种可能解决方案
print df1.reset_index(level=['id','name'])
.reindex(df2.no)
.reset_index()
.set_index(['id','no','name'])
a b
id no name
T10 103 baz 4 $25
T01 101 foo 1 $10
T32 102 bar 2 $30
如果级别顺序不重要:
print df1.reset_index(level=['id','name'])
.reindex(df2.no)
.set_index(['id','name'], append=True)
a b
no id name
103 T10 baz 4 $25
101 T01 foo 1 $10
102 T32 bar 2 $30
计时:
In [77]: %timeit df1.unstack([0, 2]).ix[df2.no].stack([1, 2]).swaplevel(0, 1)
10 loops, best of 3: 18.8 ms per loop
In [78]: %timeit df1.reset_index(level=['id','name']).reindex(df2.no).reset_index().set_index(['id','no','name'])
The slowest run took 4.41 times longer than the fastest. This could mean that an intermediate result is being cached
100 loops, best of 3: 4.41 ms per loop
解决方案
df.unstack([0, 2]).ix[df2.no].stack([1, 2]).swaplevel(0, 1)
解释
unstack([0, 2])
将索引的第一级和第三级放入列的[-2,-1]级。这隔离了您关心的级别。
ix[df2.no]
按您喜欢的顺序订购剩余级别。
stack([1, 2])
从列中获取级别并将它们放回索引中。
swaplevel(0, 1)
将索引级别放回原来的顺序。