2.Numpy配列の要素取得・入れ替え

2.1.配列の要素取得

Numpy配列の要素にアクセスするには、0から始まる順番i(インデックス)を[i]で指定します。
x[i]
配列の最後から指定する場合は、負のインデックスを指定します。
x[-i]
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

#最初から3番目の要素を取得(インデックスは0から始まる)
>>> x[2]
2

#最後から3番目の要素を取得(負のインデックスを指定)
>>> x[-3]
7

多次元配列の要素にアクセスするには、[i, j. …]で指定します。
y[i, j, …]
>>> y
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90]])

#1行6列の要素を取得する場合
>>> y[0,5]
5

#2行目の最終列の要素を取得する場合
>>> y[1,-1]
90

配列要素の書き換えもできます。
y[i, j, …] = value
>>> y
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90]])

#2行目の最終列の要素を取得する場合
>>> y[1,-1] = 900
>>> y
array([[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9],
       [  0,  10,  20,  30,  40,  50,  60,  70,  80, 900]])

ただし、整数型の配列に浮動小数点を指定すると、小数点以下は切り捨てられます。
y[i, j, …] = value
>>> y[1,-1]=0.9
>>> y
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 0, 10, 20, 30, 40, 50, 60, 70, 80,  0]])


2.2.複数要素の取得

  1. スライスによる取得
  2. リストによる取得

(1)スライスによる取得

“ : ”を使った要素の取得をスライスといい、start : stop : stepの順に指定します。
x[start: stop: step]
引数 設定 デフォルト 説明
start 省略可 0 取得を開始するIDを指定します。
stop 最終ID 0 取得を終了するID+1を指定します。
step1 省略可 1 飛び飛びにデータを取得する際のステップを指定します。
負の値を指定したばあ、後ろからデータを取得します(この場合、start > stop)。

>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

#“ : ”だけ指定すると...
>>> x[:]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

#2~4番目の要素を取得する場合
>>> x[1:4]
array([1, 2, 3]))

#6番目~最後から2番目の要素を取得する場合
>>> x[5:-2]
array([5, 6, 7])

#1個飛びで要素を取得する場合
>>> x[::2]		#stepのみ指定。start, stopはデフォルト値
array([0, 2, 4, 6, 8])

#1個飛びかつ逆順で要素を取得する場合
>>> x[::-2]
array([9, 7, 5, 3, 1])

#2~8番目の要素を2個飛びで取得する場合
>>> x[1:8:3]
array([1, 4, 7])

複数次元の要素の取得もできます。
y[start: stop: step, start: stop: step, …]
>>> z
array([[  0,   1,   2,   3,   4],
       [  0,  10,  20,  30,  40],
       [  0, 100, 200, 300, 400]])

#指定行範囲の取得
>>> z[1:]
array([[  0,  10,  20,  30,  40],
       [  0, 100, 200, 300, 400]])

>>> z[1:2]		#stopで指定した行は含まれない
array([[ 0, 10, 20, 30, 40]])

#指定列範囲の取得
>>> z[:,:3]		#行はすべて取得するため“ : ”のみで指定
array([[  0,   1,   2],
       [  0,  10,  20],
       [  0, 100, 200]])

#行、列同時に指定する場合
>>> z[1:, 2:4]	#2~最終行の2~3列の要素を取得
array([[ 20,  30],
       [200, 300]])

#stepを指定する場合
>>> z[:2,:4:2]	#列ID0~3の1列飛びの値を取得
array([[ 0,  2],
       [ 0, 20]])

節はじめに戻る

(2)配列による取得

リストまたはNumpy配列によってもNumpy配列から複数要素を取得できます。
x[[行ID1, 行ID1, …], [列ID1, 列ID2, …], …]
>>> z
array([[  0,   1,   2,   3,   4],
       [  0,  10,  20,  30,  40],
       [  0, 100, 200, 300, 400]])

#指定行範囲の取得
# 行ID=[0,1],、列ID=[1,2]の要素数は一致する必要あり
>>> z[[0,1],[1,2]]	#1行2列、2行3列の要素を取得
array([ 1, 20])

#一致しない場合
>>> z[[0,1],[1,2,3]]
Traceback (most recent call last):
  File "&l tstdin >", line 1, in < module >
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,)

#スライスと併用
>>> z[[0,1],:]
array([[ 0,  1,  2,  3,  4],
       [ 0, 10, 20, 30, 40]])

#Numpy配列で指定する場合
>>> z[np.array([0,1]),:]
array([[ 0,  1,  2,  3,  4],
       [ 0, 10, 20, 30, 40]])	#リスト指定と同じ結果

#負のIDを使った場合
>>> z[-1,[-3,-1]]
array([200, 400])

#IDの順番を入れ替えた場合
>>> z[:,[3,2,1]]
array([[  3,   2,   1],
       [ 30,  20,  10],
       [300, 200, 100]])

節はじめに戻る


2.3.要素をランダムに取得

np.random.choice( a, size, replace, p )
引数 設定 デフォルト 説明
a 必須 - ランダムに抽出する対象となる一次元Numpy配列を指定します。
size 省略可 None 配列のサイズを指定します。
省略時は、単一値を返します。
replace 省略可 True Trueの場合、復元(重複あり)で抽出します。
Falseの場合、被復元(重複なし)で抽出します。
p 省略可 None aの各要素の抽出確率を一次元Numpy配列で指定します。

>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

#配列xから3つランダムに抽出する場合(重複あり)
>>> np.random.choice(x,3)
array([4, 1, 4])

#重複なしで抽出する場合
>>> np.random.choice(x,3,replace=False)
array([5, 8, 1])

2.4.条件に合致した要素を取得

  1. 条件に合致した要素の値を取得
  2. 条件に合致した要素のIDを取得
  3. 条件に応じて要素を書き換え

(1)条件に合致した要素の値を取得

例えば、配列zの要素のうち10より小さいものを調べるには、条件文をそのまま入力すると、各要素に対してTrue(一致)、False(不一致)が返されます。
>>> z
array([[  0,   1,   2,   3,   4],
       [  0,  10,  20,  30,  40],
       [  0, 100, 200, 300, 400]])

#条件に一致する要素を確認(True=一致、False=不一致)
>>> z<10
array([[ True,  True,  True,  True,  True],
       [ True, False, False, False, False],
       [ True, False, False, False, False]])

条件に合致する要素の値を取得する場合は、次のように指定します。
z[condition]
#条件にマッチする要素の値を抽出
>>> z[z<10]
array([0, 1, 2, 3, 4, 0, 0])	#元の配列の形ではなくなる

節はじめに戻る

(2)条件に合致した要素のIDを取得

条件に合致した要素のIDが欲しい場合はwhereを使います。
numpy.where(condition)
引数 設定 デフォルト 説明
condition 必須 - 条件文を指定します。
(条件文の書き方は4.1節(3)比較演算子をご覧ください。)

#一次元配列の場合
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

#条件に合致するID
>>> np.where(x<5)
(array([0, 1, 2, 3, 4], dtype=int64),)
>>> z

#合致する要素の値を取得
>>> x[np.where(x<5)]
array([0, 1, 2, 3, 4])

多次元配列にも適用できます。
#多次元配列の場合
>>> z
array([[  0,   1,   2,   3,   4],
       [  0,  10,  20,  30,  40],
       [  0, 100, 200, 300, 400]])

#条件にマッチする要素のIDを抽出
>>> np.where(z<10)
(array([0, 0, 0, 0, 0, 1, 2], dtype=int64), array([0, 1, 2, 3, 4, 0, 0], dtype=int64))

#最初のarrayは行ID、#後ろのarrayは列IDなので、条件に合致する要素は(0,0), (0,1), (0,2), …, (2,0)

#条件に合致する要素の値を取得
>>> z[np.where(z<10)]
array([0, 1, 2, 3, 4, 0, 0])

節はじめに戻る

(3)条件に応じて要素を書き換え

numpy.where(condition, x, y)
引数 設定 デフォルト 説明
condition 必須 - 条件文を指定します。
(条件文の書き方は4.1節(3)比較演算子をご覧ください。)
x 省略可※ 条件に合致する要素をxに書き換えます。
y 省略可※ 条件に合致する要素をyに書き換えます。

x、yを片方のみ省略することはできません。 省略する場合は両方同時に省略します。
>>> z
array([[  0,   1,   2,   3,   4],
       [  0,  10,  20,  30,  40],
       [  0, 100, 200, 300, 400]])

#条件に一致する要素を確認(True=一致、False=不一致)
>>> np.where(z<10,0)
Traceback (most recent call last):
  ・・・
ValueError: either both or neither of x and y should be given

#条件に合致する場合0、しない場合1に置き換え
>>> np.where(z<10,0,1)
array([[0, 0, 0, 0, 0],
       [0, 1, 1, 1, 1],
       [0, 1, 1, 1, 1]])

#引数yのみ省略した場合
>>> np.where(z<10,0)
Traceback (most recent call last):
  ・・・
ValueError: either both or neither of x and y should be given

#条件に合致する場合何もせず、しない場合のみ0に置き換え
>>> np.where(z<10,z,0)
array([[0, 1, 2, 3, 4],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])

節はじめに戻る


2.5.部分配列のコピー

1.6節で見たように、Numpy配列は参照渡しのため、思わぬ数値の書き換えが起こることがあります。 部分配列に対してもコピーをすることで、このような問題に対象できます。
x[ ** ].copy()
>>> z
array([[  0,   1,   2,   3,   4],
       [  0,  10,  20,  30,  40],
       [  0, 100, 200, 300, 400]])

#部分配列のコピー
>>> u=z[:2,:3].copy()
>>> u
array([[ 1,  1,  2],
       [ 0, 10, 20]])


参考文献