特徴
- 異なるデータ型の要素を格納可能
- 長さ(要素数)が可変
- 要素の書き換えが可能
- インデックス(番号)で要素にアクセスが可能
- スライスが可能
- 二次元、多次元配列が可能
- インポートが必要
初期設定
numpyという標準ライブラリを使用します。標準ですのでインストールは不要です。
import numpy as np data = np.array([1, 2, 3, 4, 5]) print(data[0]) # 1と表示される # 二次元配列 data = np.array([[1, 2, 3], [4, 5, 6]]) print(data[1,1]) # 5と表示される
データ型
確認
data = np.array([1, 2, 3, 4, 5]) print(data) # [1 2 3 4 5] print(data.dtype) # int64
変更
data = np.array([1, 2, 3, 4, 5]) print(data) # [1 2 3 4 5] # 整数から浮動小数点へ data = data.astype(np.float32) print(data) # [1. 2. 3. 4. 5.] # 浮動小数点から整数へ data = data.astype(np.int64) print(data) # [1 2 3 4 5] # 整数から文字列へ data = data.astype(np.str) print(data) # ['1' '2' '3' '4' '5'] # 文字列から整数へ data = data.astype(np.int64) print(data) # [1 2 3 4 5] # 浮動小数点から文字列へ data = data.astype(np.float32) data = data.astype(np.str) print(data) # ['1.0' '2.0' '3.0' '4.0' '5.0'] # 文字列から浮動小数点へ data = data.astype(np.float32) print(data) # [1. 2. 3. 4. 5.]
要素を取得
data = np.array([1, 2, 3, 4, 5, 6]) print(data) # [1 2 3 4 5 6] print(data[0]) # 1 # 二次元配列 data = np.array([[1,2,3],[4,5,6]]) print(data) # [[1 2 3] # [4 5 6]] print(data[1,1]) # 5
二次元配列の指定の際に、スライスと間違わないように注意しましょう。
data[1:1]->data[1,1]
条件にあった要素を取得
data = np.array([1, 2, 3, 4, 5, 6]) print(data) # [1 2 3 4 5 6] y_pred = data[np.where(data > 3)] print(y_pred) # [4 5 6]
data[np.where(条件式)]
ですが、ポイントは配列の位置をnp.where(条件式)
で指定するというニュアンスです。要素の値の変更
data = np.array([1, 2, 3, 4, 5]) data[0] = 6 print(data[0]) # 6と表示される data = np.array([[1, 2, 3], [4, 5, 6]]) data[0,0] = 7 print(data[0,0]) # 7と表示される # 範囲指定(スライスを使う data = np.array([1, 2, 3, 4, 5]) data[0:3] = 6 print(data) # [6 6 6 4 5]となる data = np.array([[1, 2, 3], [4, 5, 6]]) data[0:1] = 7 print(data) # [[7 7 7] [4 5 6]]となる
スライスが少し難しいですね。
閾値で丸める
ディープラーニングでよく使います。
np.where(条件文, 条件に一致した時の値, それ以外の値)
data = np.array([1, 2, 3, 4, 5, 6]) print(data) # [1 2 3 4 5 6] y_pred = np.where(data > 3, 1, 0) print(y_pred) # [0 0 0 1 1 1]
要素を追加
末尾に追加
data = np.array([1, 2, 3]) data_new = np.append(data, 4) print(data_new) # [1 2 3 4]となる # 二次元配列 data_a = np.array([[1, 2, 3], [4, 5, 6]]) data_b = np.array([[7, 8, 9]]) # 同じ2次元でないとエラーになる。 data_new = np.append(data_a, data_b, axis=0) # , axis=0がないと一次元に戻される。 print(data_new) # [[1 2 3] # [4 5 6] # [7 8 9]]となる
多次元配列も二次元配列と同様です。
二次元配列と多次元配列は、「同じ次元にする」「axis=0をつける」に注意しましょう。
先頭に追加
data = np.array([1, 2, 3]) data_new = np.append(4, data) print(data_new) # [4 1 2 3]となる # 二次元配列 data_a = np.array([[1, 2, 3], [4, 5, 6]]) data_b = np.array([[7, 8, 9]]) # 同じ2次元でないとエラーになる。 data_new = np.append(data_b, data_a, axis=0) # , axis=0がないと一次元に戻される。 print(data_new) # [[7 8 9] # [1 2 3] # [4 5 6]]となる
appendの第一引数と第二引数を逆にするだけですね。
指定の位置に追加(挿入)
data = np.array([1, 2, 3]) data_new = np.insert(data, 2, 100) print(data_new) # [ 1 2 100 3]となる print(data_new[2]) # 100となる # 一括で追加 data_new = np.insert(data, 1, [100, 101, 102]) print(data_new) # [ 1 100 101 102 2 3]となる print(data_new[2]) # 101となる # 二次元配列 data_a = np.array([[1, 2, 3], [4, 5, 6]]) data_b = np.array([[7, 8, 9]]) # 同じ2次元でないとエラーになる。 data_new = np.insert(data_a, 1, data_b, axis=0) # , axis=0がないエラーになる。 print(data_new) # [[1 2 3] # [7 8 9] # [4 5 6]]となる
appendではなく、insertになります。
要素を削除
data = np.array([1, 2, 3]) data_new = np.delete(data, 1) # 引数は、対象データ,何番目かとなる print(data_new) # [1 3]となる # 二次元配列 data = np.array([[1, 2, 3], [4, 5, 6]]) data_new = np.delete(data, 1, 1) # 引数は、対象データ,何番目か,行(0)か列(1)かとなる print(data_new) # [[1 3] # [4 6]]となる
二次元配列の削除では、行か列の一括削除となる。考えれば当たり前だが。。。
要素の数
このあたりまでは、少し慣れがないと難解ですが、ここからがNumpyの良さになります。
全ての要素数
data = np.array([1, 2, 3]) print(len(data)) # 3となる print(data.size) # 3となる # 二次元配列 data = np.array([[1, 2, 3], [4, 5, 6]]) print(len(data)) # 2となる print(data.size) # 6となる
リスト型などと同じようにlenを使えますが二次元配列では注意が必要です。
配列の状況から取得
data = np.array([1, 2, 3, 4, 5]) print(data.shape) # (5,) print(data.shape[0]) # 5 # 二次元配列 data = np.array([[1, 2, 3],[4, 5, 6]]) print(data.shape) (2, 3) print(data.shape[0], data.shape[1]) # 2 3
Pandasと同じなので、私はこっちを利用する方が多いですね。
条件を満たす要素の数
data = np.array([1, 2, 3]) print(np.count_nonzero(data == 2)) # 1となる print(np.count_nonzero(data >= 2)) # 2となる # 二次元配列 data = np.array([[1, 2, 3], [4, 5, 6]]) print(np.count_nonzero(data == 2)) # 1となる print(np.count_nonzero(data >= 2)) # 5となる
np.sum(data == 2)も対応していますがcount_nonzeroの方が高速です。
行・列ごとに条件を満たす要素の個数
data = np.array([[1, 2, 3], [4, 5, 6]]) print(np.count_nonzero(data == 2, axis=0)) # [0 1 0]となる print(np.count_nonzero(data >= 2, axis=1)) # [2 3]となる
axisの値は列毎(0)か行毎(1)となっている。np.deleteと逆になっているようで混乱しないようにしましょう。
空(nan)と無限大(inf)の個数
data = np.array([1, np.nan, 4, np.inf]) print(data) # [ 1. nan 4. inf] print(np.isnan(data).sum()) # 1 print(np.isinf(data).sum()) # 1
np.nan
は空(欠損)、np.inf
は無限大の値を生成してくれます。要素の位置を取得
data = np.array([1, 2, 3, 4, 5]) print(np.where(data == 2)) # (array([1]),)となる print(np.where(data > 2)) # (array([2, 3, 4]),)となる # 二次元配列 data = np.array([[1, 2, 3], [4, 5, 6]]) print(np.where(data == 2)) # (array([0]), array([1]))となる。0行目の1列目という意味。 print(np.where(data > 2)) # (array([0, 1, 1, 1]), array([2, 0, 1, 2]))となる。0行目の2列目、1行目の0列目・・・という意味。
二次元配列の結果は難解そうに見えますが、噛み砕けば簡単です。