関数の実行順序は左から右で良いのでしょうか?
下の例だと、data[::-1]をしてから、sortされるので、
出力は[ 1 2 3 4 5 6 7 8 9 10]なるはずだと思っていました。
しかし[10 9 8 7 6 5 4 3 2 1]と逆に出力されます。
data = np.array([9, 2, 3, 4, 10, 6, 7, 8, 1, 5]) data[::-1].sort()
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
data[::-1]をしてから、sortされるので、
data[::-1]
してから sort されるという認識は正しいですが、ソート前の配列がどのような並び順であろうとも、ソート後の結果は同じになります。
numpy の sort は昇順ソート (小さい順) される仕様です。
今回、混乱の原因となっているのは、numpy の view と ndarray.sort() が inplace でソートする仕様というのが関係しています。
とりあえず、意図通りにソートしたい場合は、ndarray.sort() でなく、numpy.sort() をお使いください。
python
1 2import numpy as np 3 4a = np.array([9, 2, 3, 4, 10, 6, 7, 8, 1, 5]) 5 6# 小さい順 7b = np.sort(a) 8print(b) # [ 1 2 3 4 5 6 7 8 9 10] 9 10# 大きい順にソートしたい場合はあとから反転 11print(b[::-1]) # [10 9 8 7 6 5 4 3 2 1] 12 13# もしくは1次元配列なら組み込み関数 sorted() 14print(sorted(b, reverse=True)) # [10 9 8 7 6 5 4 3 2 1]
今回の原因
numpy の内部仕様が絡み、C 言語をやったことがないと少々理解しづらい話かもしれないので、補足としておきます。
numpy は多次元配列を作れますが、内部的には1次元配列でデータを管理していて、ストライドを利用して、データを参照したいときに1次元配列のどこにアクセスすればいいかを決めています。
python
1a = np.array([9, 2, 3, 4, 10, 6, 7, 8, 1, 5], dtype=np.int32) 2print(a.strides) # 4 bytes
今回のストライドを確認すると、4 bytes となっています。(int32型は1つの要素が4バイトで表される)
なので、a のインデックスが2の要素にアクセスしたい場合は、内部の1次元配列の先頭から 2*4=8 bytes 目を参照すればよいということがわかります。
今、b = a[::-1]
とした場合、これは a
を逆順にした別の配列 b
というのが作られるわけではなく、ストライドで内部の1次元配列のアクセスの仕方を変更するだけで、実態は a
と同じものになります。
ストライドは -4 bytes となっていて、b のインデックスが2の要素にアクセスしたい場合は、内部の1次元配列の 末尾から -2*4=-8 bytes 目を参照すればよいということがわかります。
b = a[::-1] print(b.base is a) # b は a の view print(b.strides) # -4 bytes
b のデータは a の内部配列を参照しているだけなので (b は a の view)、b を変更すると a も変更したことになります。
そして、ndarray.sort() は配列を直接並び変えて (inplace という) ソートするわけなので、b の配列を小さい順にソートすると、ストライドが逆になっている a の配列は大きい順に並び替えたことになります。
python
1import numpy as np 2 3a = np.array([9, 2, 3, 4, 10, 6, 7, 8, 1, 5]) 4b = a[::-1] 5 6b.sort() 7print(b) 8# [ 1 2 3 4 5 6 7 8 9 10] 9 10print(a) 11# [10 9 8 7 6 5 4 3 2 1]
投稿2019/12/20 16:01
編集2019/12/20 16:12総合スコア21956
0
リストではないので、.sort()は無理だと思うのですが...上の動作を行ってもNonenになると思います。
np.sort(data)[::-1]
仰っているのはこう言う動作だと思うのですが、この場合はソートされたものを降順にしているので、左から右に処理されています。このような回答でよろしかったでしょうか。
投稿2019/12/20 16:04
総合スコア1408
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/20 17:23
2019/12/20 17:34 編集