如果我创建如下数据框:
In [128]: test = pd.DataFrame({'a':[1,4,2,7,3,6], 'b':[2,2,2,1,1,1], 'c':[2,6,np.NaN, np.NaN, 1, np.NaN]})
In [129]: test
Out[129]:
a b c
0 1 2 2
1 4 2 6
2 2 2 NaN
3 7 1 NaN
4 3 1 1
5 6 1 NaN
基本排序按预期执行。对列c进行排序可以适当地分离纳米值。对列a和b进行多级排序按预期排序:
In [133]: test.sort(columns='c', ascending=False)
Out[133]:
a b c
5 6 1 NaN
3 7 1 NaN
2 2 2 NaN
1 4 2 6
0 1 2 2
4 3 1 1
In [134]: test.sort(columns=['b', 'a'], ascending=False)
Out[134]:
a b c
1 4 2 6
2 2 2 NaN
0 1 2 2
3 7 1 NaN
5 6 1 NaN
4 3 1 1
但是对列b和c进行多级排序并不能产生预期的结果:
In [135]: test.sort(columns=['b', 'c'], ascending=False)
Out[135]:
a b c
1 4 2 6
0 1 2 2
2 2 2 NaN
3 7 1 NaN
4 3 1 1
5 6 1 NaN
事实上,即使只在列c上进行排序,但使用多级排序命名法也失败了:
In [136]: test.sort(columns=['c'], ascending=False)
Out[136]:
a b c
1 4 2 6
0 1 2 2
2 2 2 NaN
3 7 1 NaN
4 3 1 1
5 6 1 NaN
我认为这应该给出与上面第133行完全相同的结果。这是一只熊猫虫还是有些东西我没有得到? (仅供参考,pandas v0.11.0,numpy v1.7.1,Windows 7上的python 2.7.2.5 32位)
答案 0 :(得分:2)
这是一个有趣的角落案例。请注意,即使是vanilla python也不会得到“正确”:
>>> nan = float('nan')
>>> a = [ 6, 2, nan, nan, 1, nan]
>>> sorted(a)
[2, 6, nan, nan, 1, nan]
这里的原因是因为NaN
既不大于也不小于其他元素 - 因此没有定义严格的排序。因此,python
让他们独自一人。
>>> nan > 6
False
>>> nan < 6
False
Pandas必须对单列案例进行明确检查 - 可能使用np.argsort
或np.sort
从numpy 1.4开始,np.sort
将NaN
值放在最后
答案 1 :(得分:0)
感谢上面的提醒。我想这已经是一个众所周知的问题。我想出的一个权宜之计解决方案是:
test['c2'] = test.c.fillna(value=test.c.min() - 1)
test.sort(['b', 'c2'])
test = test.drop('c2', axis = 1)
这种方法在常规numpy中不起作用,因为.min()会返回nan,但在pandas中它可以正常工作。