NumPy配列:2つの【データ参照方法】


サマリ

  • ファンシーインデックス参照
    • 場所を指定してデータを参照する
    • 指定方法はリストとタプルが利用できる
    • リスト指定とタプル指定では意味が異なるので注意が必要
      • a[[2,3]]とa[(2,3)]は違う
  • ブールインデックス参照
    • 表示する/表示しないをbool型で指定
  • 応用例
    • ReLUのコードを応用例として記載

前提

サンプルコード

ファンシーインデックス参照(2次元の場合)

データ作成

import numpy as np
a = np.arange(8).reshape(4,2)
print(a)
print(a.shape)
[[0 1]
 [2 3]
 [4 5]
 [6 7]]
(4, 2)
  • サイズ(4,2)のデータ(データフレーム)を作成
    • 4行、2列のデータ
    • 1次元目の要素数が4、2次元目の要素数が2

データ参照

b = a[2]
c = a[[3,1]]
print(b)
print(b.shape)
print(c)
print(c.shape)
[4 5]
(2,)
[[6 7]
 [2 3]]
(2, 2)
  • a[2]
    • 1次元目の要素数4のうち2を指定
    • 2は3番目(0から数えるので)
    • 3番目(3行目)は[4,5]
  • a[[3,1]]
    • リストにすると複数指定できる
    • 3(4番目、4行目)と1(2番目、2行目)なので、[6,7]と[2,3]が取り出される
  • a[[3,1]]でよくある勘違い
    • 3行目の1列目を指定しているのではないことに気を付ける
    • リストはあくまで複数指定の意味

データ参照([…][…]と複数書くとどうなる)

d = a[2][0]
e = a[[3,1]][0]
print(d)
print(d.shape)
print(e)
print(e.shape)
4
()
[6 7]
(2,)
  • d= a[2][0]
    • まずa[2]で[4,5]になる
    • 1次元配列の[0](1番目)を指定するので4
  • d.shape
    • 4はリテラルなので
    • shapeの結果は()になる(0次元)
  • e = a[[3,1]][0]
    • まずa[[3,1]]で[[6,7],[2,3]]になる
      ※2次元配列であることに注意
    • 2次元配列の[0]番目を指定するので[6,7]
  • これら2つの結果からどの要素をしていするのかしっかりと理解

データ参照(セルを指定する)

f = a[(0,1)]
print(a)
print(a.shape)
print(f)
[[0 1]
 [2 3]
 [4 5]
 [6 7]]
(4, 2)
1
  • aを再度表示した
  • f= a[(0,1)]
    • タプルで指定する
    • 1番目の次元が0(1番目)の要素
      • [0,1]を指定している
    • 2番目の次元が1(2番目)の要素
      • 1を指定している

ファンシーインデックス参照(3次元の場合)

データ作成

import numpy as np
a = np.arange(64).reshape(4,4,4)
print(a)
print(a.shape)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]
  [12 13 14 15]]

 [[16 17 18 19]
  [20 21 22 23]
  [24 25 26 27]
  [28 29 30 31]]

 [[32 33 34 35]
  [36 37 38 39]
  [40 41 42 43]
  [44 45 46 47]]

 [[48 49 50 51]
  [52 53 54 55]
  [56 57 58 59]
  [60 61 62 63]]]
(4, 4, 4)
  • サイズ(4,4,4)のデータ(データフレーム)を作成
  • 次元数は3、各次元の要素数はいずれも4

データ参照

b = a[[2,3]]
c = a[(2,3)]
print(b)
print(b.shape)
print(c)
print(c.shape)
[[[32 33 34 35]
  [36 37 38 39]
  [40 41 42 43]
  [44 45 46 47]]

 [[48 49 50 51]
  [52 53 54 55]
  [56 57 58 59]
  [60 61 62 63]]]
(2, 4, 4)
[44 45 46 47]
(4,)
  • 2次元と同じように考える
  • b = a[[2,3]]
    • 最初の次元4つの要素から2つを取り出している
    • 結果のshapeは(4,4,4)から(2,4,4)になっている
  • c = a[(2,3)]
    • 最初の次元から2(3番目)、2つ目の次元から3(4番目)を取り出す
    • 結果のshapeは(4,4,4)から(1,1,4)→最後の次元の4が残って(4, )になっている
  • 似たような指定だが、2次元の場合より違いがはっきりと見て取れる

ブールインデックス参照

import numpy as np
a = np.arange(8).reshape(4,2)
p = [True, False, True, True]
b = a[p]
print(a)
print(a.shape)
print(b)
print(b.shape)
[[0 1]
 [2 3]
 [4 5]
 [6 7]]
(4, 2)
[[0 1]
 [4 5]
 [6 7]]
(3, 2)
  • Trueになっているところだけが抽出された
  • 3次元は多分ファンシーインデックス参照と同様なので割愛

ブールインデックス参照の応用(ReLU)

ReLUの概要

  • 活性化関数
    • マイナスは0
    • プラスはそのまま

計算例

import numpy as np
a = np.random.randn(3,3)
mask = a<=0
print(a)
print(a.shape)
print(mask)
print(mask.shape)
a[mask] = 0
print(a)
print(a.shape)
[[ 2.11099799  1.40226199 -0.97763403]
 [-1.78859816 -0.69031494 -1.26675609]
 [ 1.45029502  0.50090079  1.18892022]]
(3, 3)
[[False False  True]
 [ True  True  True]
 [False False False]]
(3, 3)
[[2.11099799 1.40226199 0.        ]
 [0.         0.         0.        ]
 [1.45029502 0.50090079 1.18892022]]
(3, 3)
  • aの結果を見ると、マイナスが4か所にある
  • maskの結果を見ると、aのマイナスのところがTrueになったndarray(NumPy配列)になっている
  • マイナスの箇所が0になって、ReLUの機能を実装できている


Posted by futa