多次元配列のインデックス参照

dataをNumPyの多次元配列(numpy.ndarray)とします。

n次元配列をn次元空間に配置したときに、各次元の数値が変わる方向がその次元のaxis)になります。 各軸は、順番に0軸、1軸、2軸、…と呼びます。

たとえば3次元配列をdata[i0, i1, i2]と参照すると、以下のようになります。

  • i0: 0軸の指定

  • i1: 1軸の指定

  • i2: 2軸の指定

axisオプション

いくつかの関数では、axisオプションで演算の対象範囲を変更できます。 maxを例に見てみましょう。

data = np.array([[1, 2], [3, 4]])
print(np.max(data, axis=None))  # 全体の最大(デフォルト)
print(np.max(data, axis=0))  # 列ごとの最大
print(np.max(data, axis=1))  # 行ごとの最大

出力は下記のようになります。

4
[3 4]
[2 4]

インデックス参照

リストと同じようにdata[0]と参照できます。インデックスを指定するのでインデックス参照といいます。

data[2:4]のように、スライスも使えます。

リストとは異なりdata[i0, i1, i2]のように、各次元ごとに書くこともできます。

スライスも各次元ごと指定できます。

ファンシーインデックス参照

data[[1, 3]]のように行の指定のところでインデックスに対応するリストを指定すると、2行目と4行目だけを抜き出して使えます。 このようにインデックスのリストを使って参照する方法を、ファンシーインデックス参照と呼びます。 同じようにdata[:, [0, 2]]とすれば、1列目と3列目を取り出すことができます。

ファンシーインデックス参照は、同じインデックスを2回以上入れたり、任意の順番で指定できます。 データはコピーされるので、元のデータが変更されても取り出したデータは変更されません。

https://images.pyq.jp/numpy/numpy_base_01.png

ブールインデックス参照

ファンシーインデックス参照では、取り出したいインデックスだけのリストを指定しました。 ブールインデックス参照では、ブール型(真偽型)の値(True/False)のリストを指定します。 リストでは、各インデックスごとに取り出すか(True)取り出さないか(False)を指定します。

https://images.pyq.jp/numpy/numpy_base_02.png

ブールインデックス参照では、ファンシーインデックス参照と同じように、取り出されたものはコピーです。 また、ファンシーインデックス参照のように「同じ行などを取り出したり、順番を入れ替えたりすること」はできません。

色々な参照

いちいち、ブール型の値のリストを作成するのは、大変と思われるかもしれません。 ブロードキャストというしくみで、簡単にブール型の値のリストを作成できます。

多次元配列にスカラーを代入すると、ブロードキャストにより各要素に代入されます。 このとき、ファンシーインデックス参照やブールインデックス参照で部分的に代入できます。

import numpy as np
data1 = np.arange(12).reshape((4, -1))
data1[[1, 3]] = -1  # ファンシーインデックス参照を用いた代入
print(data1)

data2 = np.arange(12).reshape((4, -1))
data2[[False, True, False, True]] = -1  # ブールインデックス参照を用いた代入
print(data2)

data1, data2両方とも下記のように表示されます。

[[ 0  1  2]
 [-1 -1 -1]
 [ 6  7  8]
 [-1 -1 -1]]

用語集のブロードキャストも参照ください。