質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
NumPy

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

Q&A

1回答

1466閲覧

NumPyのスライスについて

Naohiro

総合スコア9

NumPy

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

0グッド

0クリップ

投稿2016/11/13 13:47

numpyのスライス機能について、得られる配列のshapeについて疑問です。

<ソースコード>
arr=np.arange(9).reshape(3,3)

arr
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])

上記のndarrayに対して、下記のスライスを行うと、array([2,8])
という結果が出るのですが、これが納得できません。

arr[[0,2],2]
array([2, 8]) ①

私が予測したのは、
array([2],[8])です。逆に、下記の様にスライスすると、私が予測した結果になります。

arr[[0,2],2:]
array([[2], ②
[8]])

そこで2点疑問です。どうして、普通のスライスだと、①の結果になるのか、
そして、":"を入れたスライスとどう違うのかを教えて欲しいです。
基本的なことですいません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

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

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

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

guest

回答1

0

凄く前の質問ですが自己満足のために書きます。

スライスの各座標に対応する引数はブロードキャストされるので、
arr[[0,2],2]はarr[[0,2],[2,2]]となります。
arrのインデックス0と2それぞれのインデックス2, 2となるので[2,8]になります。
しかし、arr[[0,2],2:]はスライスとは異なります。
試しにarr[[0,2],1:]でやってみると、

python

1>>> arr[[0,2],1:] 2array([[1, 2], 3 [7, 8]])

となり、インデックス0と2それぞれの[1:]が出力されます。
[2:]でも同様の処理がなされるため、
arr[[0,2],2:]はインデックス0と2の[2:]が出力されて[[2],[8]]になります。

###個人的な考え方
Numpyはスライス時にもブロードキャストを行うので、
arr[[0,2],2]はarr[[0,2],[2,2]]ということになります。
しかし、arr[[0,2],2:]の場合は、arr[[0,2],2]=arr[[0,2],[2,2]]にはなりません。
もしarr[[0,2],1:]だった時に、arr[[0,2],[1,2]]になったら結果が異なりますよね。

Python

1>>> arr[[0,2],1:] 2array([[1, 2], 3 [7, 8]]) 4>>> arr[[0,2],[1,2]] 5array([1, 8])

このように、0と1、2と2が対応してしまいます。
このことから、「2:」は、シンプルにnp.arange(1)+2=[2]とはなっていないことが分かります。

ではどのような計算が行われているかというと、逆にスライスの第一引数が変形されているのです。

arr[[0,2],1:]の結果は[[1,2],[7,8]]です。二次元配列上での座標を表してみましょう。
1は[0,1] 2は[0,2]
7は[2,1] 2は[2,2]となります。

よって第一引数は[[0,0],[2,2]]
第二引数は[[1,2],[1,2]]
となっています。
第一引数が変形されているので、計算を順に表してみましょう。

arr[[0,2],1:]
arr[[0,2],[1,2]]
arr[[[0],[2]],[1,2]]
arr[[[0,0],[2,2]],[1,2]]
arr[[[0,0],[2,2]],[[1,2],[1,2]]]

「:」は第一引数にも影響を与えることを考慮して、arr[[0,2],2:]の場合も考えると、
arr[[0,2],[2]]
arr[[[0],[2]],[2]]
になります。

Python

1>>> arr[[[0],[2]],[2]] 2array([[2], 3 [8]])

投稿2021/10/17 06:04

編集2021/10/18 12:20
sakuramochi_py

総合スコア32

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

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

bsdfan

2021/10/18 07:02

自己満足と書かれていることにコメントするのもアレなんですが、 スライスとAdvanced Index(配列によるindexing)は別々のものなので、一緒にして考えるのはおかしいように思います。 また、[0, 2]が[[0, 0], [2, 2]]になるのはブロードキャストとは言わないです。
sakuramochi_py

2021/10/18 11:56

コメントありがとうございます。 仰る通り、[0,2]がブロードキャストされるという記述は間違っているので編集しておきます。 Advanced Indexとスライスを混同して考えているのではなく、Advanced Indexを説明しやすいようにスライスに置き換えています。 arr[[0,2],1:]は[[1,7],[7,8]]となって、二次元配列になっているのでarr[[0,2],2:]も同様に二次元配列となって[[2],[8]]になるという、スライスとAdvanced Indexとの違いを示すほうが分かりやすいかもしれません。 Advanced Indexをスライスで考える個人的な解釈の仕方で説明するのは誤解を招く恐れがあるので、あくまで個人的な解釈の仕方で載せておくだけにしておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問