试图提炼出here问题的本质。当有问题的索引有多个级别时,似乎DataFrame.sort_index
失败,如果您尝试在添加列后执行排序,其中一个级别中包含数值。
这就是我的意思。首先,设置(请注意,所有DataFrame
中的列都处于“顺序”状态,且4
“缺失”):
import pandas as pd
import numpy as np
np.random.seed(0)
data = np.random.randn(3,4)
df_single_float = pd.DataFrame(data, index=list('abc'), columns=[1., 3., 2., 5.])
df_multi_float = pd.DataFrame(data, index=list('def'), columns=pd.MultiIndex.from_tuples([('red', i) for i in [1., 3., 2., 5.]]))
df_list = [df_single_float, df_multi_float]
这让我们来到这里:
for df in df_list:
print df
1 3 2 5
a 1.764052 0.400157 0.978738 2.240893
b 1.867558 -0.977278 0.950088 -0.151357
c -0.103219 0.410599 0.144044 1.454274
red
1 3 2 5
d 1.764052 0.400157 0.978738 2.240893
e 1.867558 -0.977278 0.950088 -0.151357
f -0.103219 0.410599 0.144044 1.454274
到目前为止一切顺利。现在让我们对它们进行排序:
for df in df_list:
print df.sort_index(axis=1)
1 2 3 5
a 1.764052 0.978738 0.400157 2.240893
b 1.867558 0.950088 -0.977278 -0.151357
c -0.103219 0.144044 0.410599 1.454274
red
1 2 3 5
d 1.764052 0.978738 0.400157 2.240893
e 1.867558 0.950088 -0.977278 -0.151357
f -0.103219 0.144044 0.410599 1.454274
完美无缺。在所有这两种情况下,列都以自然顺序出现。让我们为每个数据框添加一列:
df_single_float[4.0] = 'hello'
df_multi_float[('red', 4.0)] = 'world'
for df in df_list:
print df
1 3 2 5 4
a 1.764052 0.400157 0.978738 2.240893 hello
b 1.867558 -0.977278 0.950088 -0.151357 hello
c -0.103219 0.410599 0.144044 1.454274 hello
red red
1 3 2 5 4
d 1.764052 0.400157 0.978738 2.240893 world
e 1.867558 -0.977278 0.950088 -0.151357 world
f -0.103219 0.410599 0.144044 1.454274 world
这里看起来还不错。新栏目在右边。而且由于我们上面的不排序,旧列是“乱序”。正如所料。但现在让我们尝试对这些DataFrame
进行排序,看看它们的外观:
for df in df_list:
print df.sort_index(axis=1)
1 2 3 4 5
a 1.764052 0.978738 0.400157 hello 2.240893
b 1.867558 0.950088 -0.977278 hello -0.151357
c -0.103219 0.144044 0.410599 hello 1.454274
red red
1 2 3 5 4
d 1.764052 0.978738 0.400157 2.240893 world
e 1.867558 0.950088 -0.977278 -0.151357 world
f -0.103219 0.144044 0.410599 1.454274 world
在这里,我们看到了我要强调的问题:常规旧版Index
编辑DataFrame
正确排序。但MultiIndex
ed DataFrame
似乎没有正确排序。我已经确认使用int
代替float
数字时,行为是相同的,因为我上面有[1., 3., 2., 5.]
。我在这里做错了吗?这似乎不是你应该从排序中得到什么的预期行为,是吗?
添加版本信息:
pd.__version__
Out[9]:
'0.14.0'
In [10]:
np.__version__
Out[10]:
'1.8.1'
根据对sortlevel
的评论进行修改。我认为这不起作用:
print df_multi_float.sortlevel(axis=1)
red red
1 2 3 5 4
d 1.764052 0.978738 0.400157 2.240893 world
e 1.867558 0.950088 -0.977278 -0.151357 world
f -0.103219 0.144044 0.410599 1.454274 world