NumPy

【NumPy】配列(ndarray)の要素を参照する方法

【NumPy】配列(ndarray)の要素を参照する方法

NumPyの配列(ndarray)の要素を参照する方法を解説します。

配列(ndarray)要素の参照方法

NumPy配列(ndarray)の要素へのアクセスは、Pythonのリストの要素にアクセスする方法と同じで、角括弧([])でアクセスをすることができます。

以降で配列の要素にアクセスする方法について紹介します。

単一の要素を参照する方法

配列の中の単一要素にアクセスする場合には、以下の例のように角括弧([])で要素位置を指定することで参照することができます。

import numpy as np

data = np.arange(10)
print(f'data: {data}')

# 単一の要素にアクセスする(インデックスは0が開始なので注意)
print(f'data[0] = {data[0]}')
print(f'data[5] = {data[5]}')
print(f'data[9] = {data[9]}')
【実行結果】
data: [0 1 2 3 4 5 6 7 8 9]
data[0] = 0
data[5] = 5
data[9] = 9

上記例では、arange関数でサイズが10の配列を作成した上で要素を参照しています。インデックスの数字は0から開始することに注意しましょう。

スライスで配列の一部を取り出す方法

配列の一部を取り出したい場合には、スライスを使用することで抽出することができます。以降では、1次元配列と2次元配列のそれぞれで例を示していきます。

1次元配列の場合

1次元配列においてスライスで一部を取り出したい場合は、以下の例のように使用します。

import numpy as np

data = np.arange(10)
print(f'data: {data}')

# スライスで要素の一部を取り出す
print('\nスライスで要素の一部を取り出す')
print(f'data[2:8] = {data[2:8]}')
print(f'data[5:] = {data[5:]}')
print(f'data[:5] = {data[:5]}')

# stepを指定して値を取り出す
print('\nstepを指定して一定間隔で値を取り出す')
print(f'data[0:5:2] = {data[0:5:2]}')
print(f'data[::2] = {data[::2]}')

# 逆順で配列を取り出す
print('\n逆順で配列を取り出す')
print(f'data[::-1] = {data[::-1]}')
【実行結果】
data: [0 1 2 3 4 5 6 7 8 9]

スライスで要素の一部を取り出す
data[2:8] = [2 3 4 5 6 7]
data[5:] = [5 6 7 8 9]
data[:5] = [0 1 2 3 4]

stepを指定して一定間隔で値を取り出す
data[0:5:2] = [0 2 4]
data[::2] = [0 2 4 6 8]

逆順で配列を取り出す
data[::-1] = [9 8 7 6 5 4 3 2 1 0]

角括弧の中で[start:stop:step]というような記載方法を用います。start番目からstop-1番目までをstep刻みで取り出すという意味になります。最後はstop-1番目のインデックスまでになるため注意してください。なおstart, stop, stepの各項目は省略が可能です。

例えば上記の例で、data[2:8]というようにすると2番目の要素から7番目の要素までということになります。

また、マイナスのstepを指定することもでき、data[::-1]のようにすると逆順の配列を取得することができます。

2次元配列の場合

2次元配列の場合も参照方法は、1次元の場合と変わりません。以下の例のように、各次元ごとそれぞれで対象範囲を指定します。

import numpy as np

data = np.arange(25).reshape((5, 5))
print(f'data: \n{data}')

# 部分配列を取り出す
print('\n部分配列を取り出す')
print(f'data[:2, :2] = \n{data[:2, :2]}')
print(f'data[3:, 3:] = \n{data[3:, 3:]}')

# stepを指定して部分配列を取り出す
print('\nstepを指定して部分配列を取り出す')
print(f'data[::2, ::2] = \n{data[::2, ::2]}')
【実行結果】
data: 
[[ 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]]

部分配列を取り出す
data[:2, :2] = 
[[0 1]
 [5 6]]
data[3:, 3:] = 
[[18 19]
 [23 24]]

stepを指定して部分配列を取り出す
data[::2, ::2] = 
[[ 0  2  4]
 [10 12 14]
 [20 22 24]]

上記の例では、5×5の配列を作成し、その中で一部の部分配列を取り出しています。なお、1次元配列、2次元配列で例を見てきましたが、3次元以上のn次元配列となっても考え方は同じになります。

行や列を取り出す場合

スライスの考え方を用いると、行や列を抽出することも簡単にできます。

データ分析では一般的に行にサンプル、列に属性といった形でデータを用意するので、行や列について個別に取り出せるようにすることは重要です。

import numpy as np

data = np.arange(25).reshape((5, 5))
print(data)

# 行を取り出す
print('\n行を取り出す')
print(f'data[0, :] = {data[0, :]}')
print(f'data[0] = {data[0]}')

# 列を取り出す
print('\n列を取り出す')
print(f'data[:, 0] = {data[:, 0]}')
【実行結果】
[[ 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]]

行を取り出す
data[0, :] = [0 1 2 3 4]
data[0] = [0 1 2 3 4]

列を取り出す
data[:, 0] = [ 0  5 10 15 20]

行を取り出したいときにはdata[0, :]のように列方向のインデックスを「:」とします。「:」はすべての要素を意味するので、data[0, :]は0行目のすべての値を取り出すという意味になります。複数行取り出したい場合は、data[0:2, :]のようにすれば複数行取り出せることはわかるかと思います。

なお、data[0]のように列方向の要素を記載しない場合は、data[0, :]と結果が同じになります。

列を取り出したい場合も考え方は同様です。data[:, 0]というようにすると、0列目のすべての値を取り出すという意味になります。

配列(ndarray)のスライスはビューであるので注意

上記のスライスで取得できる変数は元の配列のビューであるため、値を変更すると元の配列の値も変わってしまいます。

そのため、元の配列を変更したくない場合は、配列をcopy関数を利用してコピーして使用する必要があるので注意してください。

ここで注意としているのは「NumPyの配列(ndarray)のスライス」と「Python組み込みのlistのスライス」の違いがあるため間違える可能性があるからです。スライスの違いについては「「NumPy配列(ndarray)のスライス」と「Python組み込みのlistのスライス」の違い」でまとめているので興味があれば参考にしてください。

その他のアクセス方法:ファンシーインデックス(Fancy Indexing)

その他の要素へのアクセス方法としてNumPyで特徴的な方法として、ファンシーインデックス(Fancy Indexing)と呼ばれている考え方があります。

ファンシーインデックスについては「ファンシーインデックス(Fancy Indexing)の基本」でまとめているので興味があれば参考にしてください。