#index
#概要
ここでは色々な計算テクニックを身に付けるために、Numpyのインデックス参照やブロードキャストについて見ていく。
#今回使うライブラリのインポート
import numpy as np
import numpy.random as random
import scipy as sp
import matplotlib.pyplot as plt
import matplotlib as mpl
#Numpyを使った計算の応用
##インデック参照
sample_array = np.arange(10)
print('sample_array:',sample_array)
sample_array: [0 1 2 3 4 5 6 7 8 9]
上の結果からわかるようにsample_array
は0から9までの数字(配列)を作成している。
連番や等差数列を生成するnumpy.arange関数の使い方
次にスライス操作を行ってみる。
#元のデータ
print(sample_array)
# 前から数字を5つ取得して、sample_array_sliceに入れる(スライス)
sample_array_slice = sample_array[0:5]
print(sample_array_slice)
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4]
次は、sample_array_sliceの先頭から3つを10という値に置き換える。
この時、元の変数であるsample_arrayの値も変わっていることに注意
# sample_array_sliceの3文字目までは、10で置換
sample_array_slice[0:3] = 10
print(sample_array_slice)
# スライスの変更はオリジナルのリストの要素も変更されていることに注意
print(sample_array)
[10 10 10 3 4]
[10 10 10 3 4 5 6 7 8 9]
##データのコピー
先ほどの代入元の変数の値も変わってしまわないように元のデータを参照せず、元のデータをコピーした物を参照させるようにすれば良い。
# copyして別のobjectを作成
sample_array_copy = np.copy(sample_array)
print(sample_array_copy)
sample_array_copy[0:3] = 20
print(sample_array_copy)
# 元のリストの要素は変更されていない
print(sample_array)
[10 10 10 3 4 5 6 7 8 9]
[20 20 20 3 4 5 6 7 8 9]
[10 10 10 3 4 5 6 7 8 9]
##ブールインデックス参照
bool(True or False)
によって、どのデータを取り出すかを決める機能。
sample_namesは、「a」「b」「c」「d」「a」という値を要素として持つ要素数5の配列、dataは、標準正規乱数からなる5×5の配列を作成。
sample_names = np.array(['a','b','c','d','a'])
random.seed(0) # 発生する乱数の種を固定
data = random.randn(5,5)
print(sample_names)
print(data)
['a' 'b' 'c' 'd' 'a']
[[ 1.764 0.4 0.979 2.241 1.868] #a
[-0.977 0.95 -0.151 -0.103 0.411] #b
[ 0.144 1.454 0.761 0.122 0.444] #c
[ 0.334 1.494 -0.205 0.313 -0.854] #d
[-2.553 0.654 0.864 -0.742 2.27 ]] #a
要素の値が「'a'」である部分だけTrueになる結果を取り出す
sample_names == 'a'
array([ True, False, False, False, True])
data変数の[]の中に条件として指定すると、Trueになっている箇所のデータだけが取り出せる
data[sample_names == 'a']
array([[ 1.764, 0.4 , 0.979, 2.241, 1.868],
[-2.553, 0.654, 0.864, -0.742, 2.27 ]])
##条件制御
numpy.where(条件の配列, Xのデータ, Yのデータ)
これは、条件の配列がTrueのときは 𝑋 のデータ、そうでなければ 𝑌 のデータが取り出される。
cond_data = np.array([True,True,False,False,True])
x_array= np.array([1,2,3,4,5])
y_array= np.array([100,200,300,400,500])
print(np.where(cond_data,x_array,y_array))
[ 1 2 300 400 5]
#Numpyの演算処理
##重複の削除
unique
を使うことで、要素の重複を削除できる
cond_data = np.array(['ばなな','りんご','パイナップル','ばなな','パイナップル'])
print(cond_data)
# 重複削除
print(np.unique(cond_data))
['ばなな' 'りんご' 'パイナップル' 'ばなな' 'パイナップル']
['ばなな' 'りんご' 'パイナップル']
##ユニバーサル関数
全ての要素に関数を適用できる
sample_data = np.arange(10)
print('元のデータ:', sample_data)
print('すべての要素の平方根:',np.sqrt(sample_data))
print('すべての要素のネイピア指数関数:',np.exp(sample_data))
元のデータ: [0 1 2 3 4 5 6 7 8 9]
すべての要素の平方根: [0. 1. 1.414 1.732 2. 2.236 2.449 2.646 2.828 3. ]
すべての要素のネイピア指数関数: [1.000e+00 2.718e+00 7.389e+00 2.009e+01 5.460e+01 1.484e+02 4.034e+02
1.097e+03 2.981e+03 8.103e+03]
##最小、最大、平均、合計の計算
Pandansでもできるが、Numpyでもできる
data = np.arange(9).reshape(3,3)
print(data)
print('最小値:',data.min())
print('最大値:',data.max())
print('平均:',data.mean())
print('合計:',data.sum())
# 行列を指定して合計値を求める
print('行の合計:',data.sum(axis=1))
print('列の合計:',data.sum(axis=0))
[[0 1 2]
[3 4 5]
[6 7 8]]
最小値: 0
最大値: 8
平均: 4.0
合計: 36
行の合計: [ 3 12 21]
列の合計: [ 9 12 15]
axis = 0, axis=1 がわからなくなった人へ
##真偽値の判定
any
やall
を使うと、要素の条件判定ができる。
any
:いずれか少なくとも1つ満たすものがあればTrue
all
:全て満たす場合にTrue
cond_data = np.array([True,True,False,False,True])
print('Trueが少なくとも1つあるかどうか:',cond_data.any())
print('すべてTrueかどうか:',cond_data.all())
Trueが少なくとも1つあるかどうか: True
すべてTrueかどうか: False
条件を指定してからsumを指定すると、条件に合致する要素の個数を調べられる。
data2 = np.arange(9).reshape(3,3)
print(data2)
print('5より大きい数字がいくつあるか:',(data2>5).sum())
[[0 1 2]
[3 4 5]
[6 7 8]]
5より大きい数字がいくつあるか: 3
##対角成分の計算
対角成分(行列の左上から右下にかけての対角線上に並ぶ成分)
data3 = np.arange(9).reshape(3,3)
print(data3)
print('対角成分:',np.diag(data3))
print('対角成分の和:',np.trace(data3))
[[0 1 2]
[3 4 5]
[6 7 8]]
対角成分: [0 4 8]
対角成分の和: 12
#配列操作とブロードキャスト
##再形成
sample_array = np.arange(10)
sample_array
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
reshape(2, 5)
で2行5列の行列に再形成
sample_array2 = sample_array.reshape(2,5)
sample_array2
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
5行2列の行列を再形成
sample_array2.reshape(5,2)
array([[0, 1],
[2, 3],
[4, 5],
[6, 7],
[8, 9]])
##データの結合
concatenate
を使うと、データの結合が可能
sample_array3 = np.array([[1,2,3],[4,5,6]])
sample_array4 = np.array([[7,8,9],[10,11,12]])
# 行方向に結合。パラメータのaxisに0を指定
np.concatenate([sample_array3,sample_array4],axis=0)
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
行方向の結合は、vstack
でも可能
np.vstack((sample_array3,sample_array4))
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
列方向の結合はaxisに1を設定する。
np.concatenate([sample_array3,sample_array4],axis=1)
array([[ 1, 2, 3, 7, 8, 9],
[ 4, 5, 6, 10, 11, 12]])
列方向の結合は、hstack
でも可能。
np.hstack((sample_array3,sample_array4))
array([[ 1, 2, 3, 7, 8, 9],
[ 4, 5, 6, 10, 11, 12]])
##配列の分割
split
を使うと配列を分割できる。
splitに[1,3]というパラメータを指定することによって以下のように分割させる。
①1の手前までの行(0番目の行)
②1から3の手前までの行(1番目と2番目の行)
③3以降全ての行(3番目の行)
# sample_array_vstackを3つに分割し、first、seocnd、thirdという3つの変数に代入
first,second,third=np.split(sample_array_vstack,[1,3])
print(first) #出力: [[1 2 3]]
print(second) #出力: [[4 5 6]
# [7 8 9]]
print(third) #出力: [[10 11 12]]
##繰り返し処理
repeat
を使うと、それぞれの要素を繰り返し生成できる
data4 = np.arange(5)
print(data4)
data4.repeat(3)
[0 1 2 3 4]
array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
##ブロードキャスト
配列の大きさが異なっている時、自動的に要素をコピーして、対象の大きさを揃える機能。
NumPyのブロードキャストのメモ
機械学習の Python との出会い
公式
sample_array = np.arange(10)
print(sample_array)
sample_array + 3
[0 1 2 3 4 5 6 7 8 9]
array([ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])