Numpy
Numpyの概要
- データ型は揃える必要がある
データ構造は以下
- 配列用Ndarray
- 行列用matrix
インポート
import.py
import numpy as np
配列作成 array
makearray.py
# 1次元配列
a = np.array([1, 2, 3])
# 2次元配列
b = np.array([[4, 5, 6],[7, 8, 9]])
要素の確認 type,shape,dtype
check.py
a
>> array([1, 2, 3])
print(a)
>> [1, 2, 3]
type(a)
>> numpy.ndarray
a.dtype
>>dtype('int64')
a.shape
>>(3,)
b.shape
>>(2, 3)
配列の変形 reshape
reshape.py
c1 = np.array([0, 1, 2, 3, 4, 5])
c2 = np.reshape((2,3))
c2
>> array([[0, 1, 2],[3, 4, 5]])
データ型指定と変更 dtype,astype
dtype.py
d = np.array([1, 2], dtype=np.int16)
d
>> array([1, 2],dtype=int16)
d.dtype
>> dtype('1nt16')
d.astype(np.float16)
>>array([1, 2], dtype=float16)
インデックスとスライス
index.py
a = array([[1, 2, 3],
[4, 5, 6]])
# インデックス指定
a[1]
>>array([4, 5, 6])
a[1,2]
>>6
# スライス指定
a[:,1]
>>array([2,5])
a[:,[0,2]]
>>array([[1,3],
[4,6]])
データ再代入
datachange.py
a = np.array([[1, 2, 3],[4, 5, 6]])
# インデックス指定
a[1, 2] = 7
a
>>array([[1, 2, 3],
[4, 5, 7]])
# スライス指定
a[:, 2] = 8
a
>>array([[1, 2, 8],[4, 5, 8]])
深いコピーと浅いコピー ravel,flatten
ravelは参照、flattenはコピー
shallowanddeep.py
a = np.array([1, 2, 3])
>>array([1, 2, 3])
a1 = a
a1[1] = 5
a1
>>array([1, 5, 4])
# 浅いコピーの為元のaの要素も影響を受ける
a
>>array([1, 5, 4])
a2 = a.copy()
a2[0] = 6
a2
>>array([6, 5, 4])
# 深いコピーの為元のaの要素も影響を受けない
a
>>array([1, 5, 4])
#ravel,flattenの違いについて確認
c = np.array([[0, 1, 2],[3, 4, 5]])
c2 = c.ravel()
c3 = c.flatten()
c2[0] = 6
c3[1] = 7
# ravel(参照)
c2
>>array([[6, 1, 2],[3, 4, 5]])
# flatten(コピー)
c3
>> array([[0, 7, 2],[3, 4, 5]])
c #ravelの影響しか受けない
>>array([[6, 1, 2],[3, 4, 5]]
python標準リストとNumpyのスライスの扱いの違い
標準リストはコピーが渡されるが、
Numpyのスライスは参照なので注意
list.py
# Python標準
py_list1 = [0, 1]
py_list2 = py_list1[:]
py_list[0] = 2
print(py_list1)
print(py_list2)
>>[0,1]
[2,1]
# Numpyの場合
np_array1 = [0, 1]
np_array2 = np_array1[:]
np_array[0] = 2
print(np_array1)
print(np_array2)
>>[2 1]
[2 1]
数列の作成 arange
arange.py
import numpy as np
arr = np.arange(start=0, stop=10, step=2)
print(arr)
>>array([0 2 4 6 8])
乱数 seed,random,rand,randint,uniform,randn
- seed(seed値)
乱数生成のシード(初期値)を設定
同じシード値を使用すると、同じ乱数のシーケンスが生成される
seed.py
# Seed値の設定
np.random.seed(123)
【一様乱数】
- random
0~1範囲のランダムの数値をタプルの行列分作成
返り値:浮動点少数
ramdom.py
# 3行2列の一様乱数を作成
np.random.random((3, 2))
>>>array([[0.69646919, 0.28613933],
[0.22685145, 0.55131477],
[0.71946897, 0.42310646]])
- rand(d0, ..., dn次元)
引数に次元を与え、0から1までの範囲で一様分布に従う乱数を生成
出力形式はNumPy配列、返り値は浮動小数点数
rand.py
np.random.rand(4, 2)
>>> array([[0.69646919, 0.28613933],
[0.22685145, 0.55131477],
[0.71946897, 0.42310646],
[0.9807642 , 0.68482974]])
- randint
引数:low, high=None, size=None, dtype='l'
lowからhigh(highは含まれない)までの範囲で整数の乱数を生成
sizeは出力の形状を指定
randint.py
np.random.randint(1, 10)
>>>3
- uniform
引数:low=0.0, high=1.0, size=None
指定した範囲で一様分布に従う乱数を生成
lowは範囲の下限、highは上限を指定
sizeは指定しない場合、単一の整数が生成される
返り値は浮動点少数
uniform.py
# Size指定なし
np.random.uniform()
>>>0.48093190148436094
# 始点、終点指定
np.random.uniform(2,5.0)
>>>4.089407556793585
# # high,配列指定パターン
np.random.uniform(3.0, size=(4,4))
>>>array([[1.60706163, 2.42772133, 2.54629709, 1.89737046],
[1.56106206, 2.15378708, 1.0384716 , 1.63034052],
[2.0381362 , 2.21576496, 2.31364397, 1.54190059],
[2.12285551, 2.88064421, 2.20391149, 1.52400919]])
# 配列のみ指定のパターン
np.random.uniform(size=(4, 3))
>>>array([[0.69646919, 0.28613933, 0.22685145],
[0.55131477, 0.71946897, 0.42310646],
[0.9807642 , 0.68482974, 0.4809319 ],
[0.39211752, 0.34317802, 0.72904971]])
【正規分布】
- randn(d0, d1, ..., dn)
引数は全てオプション
randn.py
# 標準正規分布からランダムな浮動小数点数を1つ生成
np.random.randn()
>>>-2.426679243393074
# 標準正規分布からランダムな浮動小数点数を5つ生成(1次元配列)
np.random.randn(5)
>>>array([-0.42891263, 1.26593626, -0.8667404 , -0.67888615, -0.09470897])
# 標準正規分布からランダムな浮動小数点数で3行2列の2次元配列を生成
np.random.randn(3, 2)
>>>array([[ 1.49138963, -0.638902 ],
[-0.44398196, -0.43435128],
[ 2.20593008, 2.18678609]])
数列作成 zeros,ones,eye,full,nan,linspace,diff
同じ要素の配列を作成
- zeros: 指定した形状とタイプの新しい配列を作成し、要素をゼロで初期化
- ones: 指定した形状とタイプの新しい配列を作成し、要素を1で初期化
onezeros.py
np.zeros(4)
>>>array([0., 0., 0., 0.])
np.zeros((2,3))
>>>array([[0., 0., 0.],
[0., 0., 0.]])
np.ones(2)
>>array([1., 1.])
np.ones((2,3))
>>>array([[1., 1., 1.],
[1., 1., 1.]])
単位行列の作成 eye
- 左下から右下にかけて対角要素1を埋める正方行列を作成する
- 要素数nを指定してn行n列を作成できる。※正方行列なので引数は1つ
eye.py
np.eye(3)
>>>array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
指定値で埋める full
- full: 指定した値で満たされた配列を生成します
full.py
# 1次元配列の場合
np.full(3, 3.14)
>>>array([3.14, 3.14, 3.14])
# 2次元配列の場合
np.full((2,4),np.pi)
>>>array([[3.14159265, 3.14159265, 3.14159265, 3.14159265],
[3.14159265, 3.14159265, 3.14159265, 3.14159265]])
欠損値の生成 nan
行列にnanを含むときは浮動点少数が返却される
nan.py
# 1次元配列
np.nan
>>>nan
# 2次元配列
np.array([1,2, np.nan])
>>>array([ 1., 2., nan])
範囲指定で均等割りデータを作成 linspace
指定した間隔で等間隔の数値を生成
返り値は浮動点少数
引数:start, stop, num,endpoint, retstep, dtype
必須
start : 数列の開始値を指定
stop : 数列の終了値を指定
オプション
num : int型 生成する数を指定。デフォルトは50
endpoint : bool型
True(デフォルト) 終了値はstopを含む
False 終了値はstopを含まない
retstep : bool型 Trueの時、数列以外にステップ(隣接する値間の差)も返す
dtype : データ型 配列のデータ型を指定。指定しない場合、start、stop、numのデータ型から推測される
以下は0~1までの値範囲を5等分した配列を作成
linspace.py
# 0から1までの数値を5等分
np.linspace(0, 1, 5)
>>>array([0. , 0.25, 0.5 , 0.75, 1. ])
# 20分割の行列を生成
np.linspace(0, np.pi, 21)
>>>array([0. , 0.15707963, 0.31415927, 0.4712389 , 0.62831853,
0.78539816, 0.9424778 , 1.09955743, 1.25663706, 1.41371669,
1.57079633, 1.72787596, 1.88495559, 2.04203522, 2.19911486,
2.35619449, 2.51327412, 2.67035376, 2.82743339, 2.98451302,
3.14159265])
# retstepオプションの使用(差分がいくつかを返却する)
np.linspace(0, 1, 5, retstep=True)
>>>(array([0. , 0.25, 0.5 , 0.75, 1. ]), 0.25)
差分を表示 diff
各要素の差分を表示する。
diff.py
l = np.array([2, 6, 4, 6, 1, 3])
np.diff(l)
>>>array([ 4, -2, 2, -5, 2])
配列の連結 concatenate
concatenate関数
引数:axis = 0(列),1(行)
concatenate.py
# 例題用の配列作成
a = np.array([1, 5, 4])
a1 = np.array([1, 5, 4])
>>>[1 5 4]
[1 5 4]
# 連結
np.concatenate([a, a1])
>>>array([1, 5, 4, 1, 5, 4])
# 例題用の配列作成
b = np.array([[1,2,3],[4,5,6]])
b1 = np.array([[10,11,12],[13,14,15]])
# 列方向→への連結
np.concatenate([b,b1],axis=0)
>>>array([[ 1, 2, 3, 10, 11, 12],
[ 4, 5, 6, 13, 14, 15]])
# 行方向↓への連結
np.concatenate([b,b1],axis=1)
>>>array([[ 1, 2, 3],
[ 4, 5, 6],
[10, 11, 12],
[13, 14, 15]])
スタックhstack,vstack
前提としてhstackは列数、vstackは行数があっていること
hstack.py
# hstack
np.hstack([b,b1])
>>>array([[ 1, 2, 3, 10, 11, 12],
[ 4, 5, 6, 13, 14, 15]])
vstack.py
# vstack
np.vstack([c,c1])
>>>array([[ 1, 2, 8],
[ 4, 5, 8],
[30, 60, 45]])
分割 hsplit,vsplit
返り値は2つ
hsplit.py
# 例題用の配列作成
b3 = np.array([[ 1, 2, 8],
[ 4, 5, 8],
[30, 60, 45]])
# hspilt
first, second = np.hsplit(b3, [2])
# 返り値1
first
>>>>array([[ 1, 2],
[ 4, 5],
[30, 60]])
# 返り値2
second
>>>array([[ 8],
[ 8],
[45]])
vsplit/py
# vspilt
first1, second1 = np.vsplit(b3,[2])
# 返り値1
first1
>>>array([[1, 2, 8],
[4, 5, 8]])
# 返り値2
second1
>>>array([[10, 11, 12],
[13, 14, 15]])
転置 T
n行m列の配列をm行n列に変形する
T.py
a = array([[1, 2, 8],
[4, 5, 8]])
a.T
>>>array([[1, 4],
[2, 5],
[8, 8]])
次元追加 newaxis
newaxis.py
a = array([1, 5, 4])
# 列方向に次元追加
a[np.newaxis,:]
>>>array([[1, 5, 4]])
# 行方向に次元追加
a[:,np.newaxis]
>>>array([[1],
[5],
[4]])
# 2次元の場合
b = array([[1, 2, 8],
[4, 5, 8]])
# 列方向に次元追加
b[:,np.newaxis]
>>>array([[[1, 2, 8]],
[[4, 5, 8]]])
# 行方向に次元追加
b[np.newaxis,:]
>>>array([[[1, 2, 8],
[4, 5, 8]]])
グリッドデータの作成
2つの1次元配列を入力として受け取り、それらをグリッドに展開する
meshgrid.py
# グリッドデータの作成
m = np.arange(0,4)
>>>array([0, 1, 2, 3])
n = np.arange(4,7)
>>>array([4, 5, 6])
# グリッドデータ作成
xx, yy = np.meshgrid(m, n)
# 行方向に要素数[n]個分繰り返す
xx
>>>array([[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]])
# 列方向に要素[n]を要素数[m]個分繰り返す
yy
>>>array([[4, 4, 4, 4],
[5, 5, 5, 5],
[6, 6, 6, 6]])
ユニバーサルファンクション abs sin cos tan log exp
要素ごとに配列操作を行うための関数
abs(絶対値)
abs.py
a = array([[-3, -2, -1],
[ 0, 1, 2]])
np.abs(a)
>>>array([[3, 2, 1],
[0, 1, 2]])
sin関数
sin.py
b = np.array([-1. , -0.77777778, -0.55555556, -0.33333333, -0.11111111,
0.11111111, 0.33333333, 0.55555556, 0.77777778, 1. ])
np.sin(b)
>>>array([-0.84147098, -0.70169788, -0.52741539, -0.3271947 , -0.11088263,
0.11088263, 0.3271947 , 0.52741539, 0.70169788, 0.84147098])
cos関数
cos.py
np.cos(b)
>>>array([0.54030231, 0.71247462, 0.84960756, 0.94495695, 0.99383351,
0.99383351, 0.94495695, 0.84960756, 0.71247462, 0.54030231])
log関数
log.py
c = array([0, 1, 2])
# log関数(自然対数)
np.log(c)
>>>array([ -inf, 0. , 0.69314718])
# -infはマイナス無限大を表す
d = np.array([[1, 2, 3],
[4, 5, 6]])
# log関数(常用対数)
np.log10(d)
>>>array([[0. , 0.30103 , 0.47712125],
[0.60205999, 0.69897 , 0.77815125]])
自然対数の底
exp.py
e = np.array([0, 1, 2])
np.exp(a)
>>>array([1. , 2.71828183, 7.3890561 ])
ブロードキャスト
和
cast.py
a = np.array([0, 1, 2])
# 和
a + 10
>>>array([10, 11, 12])
b = np.array([[-3, -2, -1],
[ 0, 1, 2]])
# 和2
# 次元数が異なる配列通しの計算
a + b
>>>array([[-3, -1, 1],
[ 0, 2, 4]])
# 和3
a1 = a[:,np.newaxis]
>>>array([[0],
[1],
[2]])
# a(3行1列) + a1(3行1列)の計算
# 引き延ばされて計算される。
# [0, 1, 2] + [0, 0, 0]
# [0, 1, 2] + [1, 1, 1]
# [0, 1, 2] + [2, 2, 2]
a + a1
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])
差
subtraction.py
a = np.array([0, 1, 2])
b = np.array([[-3, -2, -1],
[ 0, 1, 2]])
# 差
b - a
>>>array([[-3, -3, -3],
[ 0, 0, 0]])
# 差2
a - b
>>>array([[3, 3, 3],
[0, 0, 0]])
掛け算
multiplication.py
b * 2
>>>array([[-6, -4, -2],
[ 0, 2, 4]])
a * b
>>>array([[ 0, -2, -2],
[ 0, 1, 4]])
割り算
division.py
a = np.array([0, 1, 2])
c = np.array([[1, 2, 3],
[4, 5, 6]])
a / 2
>>>array([0. , 0.5, 1. ])
a / c
>>>array([[0. , 0.5 , 0.66666667],
[0. , 0.2 , 0.33333333]])
べき乗
exponentiation.py
b ** 2
>>>array([[9, 4, 1],
[0, 1, 4]])
平均値
mean.py
c = array([[1, 2, 3],
[4, 5, 6]])
np.mean(c)
>>>3.5
ドッド積
m行n列 n行m列 のような行列は掛け算が可能。
dotproduct.py
a = np.array([0, 1, 2])
b = np.array([[-3, -2, -1],
[ 0, 1, 2]])
b @ a
>>>array([-4, 5])
# b @ aは(2, 3) @ (1, 3)となり、行列積の条件を満たさないように見えるが、
# 実際にはnumpyは1次元配列と2次元配列のドット積を計算する際に特別な処理を行う。
# 具体的には、1次元配列aが2次元配列bとドット積を計算する場合、numpyはaを(3,)として扱い、bの各行とaのドット積を計算する。
d = np.array([[0, 1],
[2, 3],
[4, 5]])
# 2行3列× 3行2列なので2行2列の配列が返却される m,n・n,m = m,m
b @ d
>>>array([[ -8, -14],
[ 10, 13]])
# 3行2列× 2行3列なので3行3列の配列が返却される m,n・n,m = m,m
d @ b
>>>array([[ 0, 1, 2],
[ -6, -1, 4],
[-12, -3, 6]])
判定
decision.py
a = np.array([0, 1, 2])
b = np.array([[-3 -2 -1],
[ 0 1 2]])
a > 1
>>>array([False, False, True])
# 0以上の要素数をカウント
np.sum(b > 0)
>>>2
# 配列要素いずれかがTrueの場合Trueを返す
np.any(b > 0)
>>>True
# 全ての要素がb > 0を満たすか
np.all(b > 0)
>>>False
# 条件に合致した配列のみを出力する
b[b > 0]
>>>array([1, 2])
# count_nonzero関数 0より大きい値の要素数を返す。
np.count_nonzero(b > 0)
>>>2
# 各要素を比較
b == c
>>>array([[False, False, False],
[False, False, False]])
# ブロードキャストによって配列を変形し判定される
a == b
>>>array([[False, False, False],
[ True, True, True]])
c = array([[1, 2, 3],
[4, 5, 6]])
# |(または)でbとcまたはaとcが等しい場所を見つける。
# b == c にはTrueがないので評価されず、a == cの2列目がTrueになるので評価され、
# 返される値は2行目がTrueになる。
(b == c)|(a == b)
>>>array([[False, False, False],
[ True, True, True]])
# allcloseは各要素の絶対値を比較し差が非常に小さい、近似的に等しい(1e-05の範囲)時にTrueを返す。
# 1e-05は科学的記数法で、1 * 10^-5を表し、これは0.00001と等しい
# allclose関数がTrueを返すのは比較対象の絶対値が0.00001以下の限りなく等しい場合になる。
np.allclose(b,c)
>>>False
# 比較対象となる配列の絶対値の範囲を指定できる。
# 以下は10以下の場合Trueとみなす。
np.allclose(b,c, atol=10)
>>>True