🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

376閲覧

関数の実行順序 data[::-1].sort()

gjgjgjgjg

総合スコア14

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/12/20 15:16

関数の実行順序は左から右で良いのでしょうか?

下の例だと、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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gjgjgjgjg

2019/12/20 17:23

ありがとうございます。 スライスはあくまでも見る順番がこうだよと示しているだけで、 その後の処理で参照しているデータが変われば、適応されるんですね。 このようなスライスの処理は、処理の最初でも最後でも結果には影響しないんですね。 結局どこで見る順番がこうだと指示しても同じなので。
tiitoi

2019/12/20 17:34 編集

> スライスはあくまでも見る順番がこうだよと示しているだけで、 その認識であってます。 見る順番を変えているだけでデータは共有しているので、スライス後のデータを変更するとスライス前のデータも変更されます。 他にも reshape などデータを見る順番を変えれば済む場合は、view を作成するだけになります。 逆に、データを見る順番を変えるだけではどうにもならない場合はコピーが作られるようになっています。([] による指定でも boolean indexing, fancy indexing などはコピー) numpy がこのような仕様になっているのは、コピーはコストがかかるので、計算コストやメモリ使用量をへらすために極力 view で済ませるようになっています。 view の話は以下などを参考にしてみてください。 https://deepage.net/features/numpy-copyview.html > 処理の最初でも最後でも結果には影響しないんですね。 「ソート後の結果は同じになります。」と書いたのは、ソート前のデータが [9, 2, 3, 4, 10, 6, 7, 8, 1, 5] でもそれを反転させた [5, 1, 8, 7, 6, 10, 4, 3, 2, 9] でも 小さい順に並びかえるのがソートなのだから、ソートしたあとの結果は同じになるという意味で書きました。 質問だと、ソート前に [::-1] する場合としない場合でソート後の結果がかわると思われているのかと思ったので、その点は間違いなので書きました。
guest

0

リストではないので、.sort()は無理だと思うのですが...上の動作を行ってもNonenになると思います。

np.sort(data)[::-1]

仰っているのはこう言う動作だと思うのですが、この場合はソートされたものを降順にしているので、左から右に処理されています。このような回答でよろしかったでしょうか。

投稿2019/12/20 16:04

bamboo-nova

総合スコア1408

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bamboo-nova

2019/12/20 16:07

すみません、解釈を誤っておりました...。ご迷惑をお掛けしました。tiitoiさんありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問