2

如果我制作如下数据框:

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 进行排序适当地隔离了 nan 值。按预期对列 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 32bit)

4

2 回答 2

4

这是一个有趣的极端案例。请注意,即使是香草 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.argsortnp.sort从 numpy 1.4 开始,np.sortNaN值放在末尾。

于 2013-11-13T00:22:27.657 回答
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 中它可以正常工作。

于 2013-11-13T04:25:21.567 回答