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 行目とまったく同じ結果が得られるはずだったと思います。これはパンダのバグですか、それとも私が得ていないものがありますか? (参考までに、Windows 7 では pandas v0.11.0、numpy v1.7.1、python 2.7.2.5 32 ビット)

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 は、単一列の場合に明示的なチェックを行う必要があります。おそらくnumpy 1.4 からnp.argsortorを使用して、値を最後に配置します。np.sortnp.sortNaN

于 2013-11-13T00:22:27.657 に答える