python

【python】Numpy

Numpyとは?

Pythonで高速に(効率的に)数値計算を行う機能を提供するパッケージです。 Pythonが科学計算分野で広く使われることに貢献したパッケージの1つです。

パッケージの使い方

import numpy 
import numpy as np

配列を作る Pythonにはすでに見てきたようにリストがありますが、NumPyではリストに似た“配列”と呼ばれるデータ構造を利用していきます。numpy.array([[0, 1], [2, 3, 4]]) といったようなサイズの異なる2次元配列を与えることもできます。

 Numpyのarrayを作る

array()

リストを引数に受け取り、nupy用の配列を作成します。

#一次元配列 
a = numpy.array([0,1,2,3])
#[0 1 2 3] 

#2次元配列 
b = numpy.array([[0, 1, 2], [3, 4, 5]]) 
# [[0 1 2] 
# [3 4 5]]
matrix()
arange()
# 0から4までの整数を持つ配列を作る 
print(numpy.arange(5)) 
# [0 1 2 3 4] 

# 1から9までの整数のうち奇数の配列を作る 
#(1から9まで2ステップずつ整数を取り出す)
 print(numpy.arange(1, 10, 2)) 
# [1 3 5 7 9]
reshape()

メソッドを使って後から形を変更できます。また変形後の要素数は変形前の要素数と同じになるような形でなければなりません。

print("6", numpy.arange(6)) 
print("2×3", numpy.arange(6).reshape(2, 3)) 
6 [0 1 2 3 4 5] 
2×3 [[0 1 2] [3 4 5]] 
# 要素数6を 要素3x3=9の形に変形はできない。 
numpy.arange(6).reshape(3, 3)
linspace()

関数は指定した区間内から等間隔で値を取得します

# 2.0から3.0までの区間に5つの値を等間隔で作成する
#(つまり、0.25ステップ)
print(numpy.linspace(2.0, 3.0, num=5))
#[2.   2.25 2.5  2.75 3.  ]

#区間の終了を含めないときは endpoint=False を指定
print(numpy.linspace(2.0, 3.0, num=5, endpoint=False))
#[2.  2.2 2.4 2.6 2.8]

#間隔も同時に取得したい場合は retstep=True を指定
a, step = numpy.linspace(2.0, 3.0, num=5, retstep=True)
print(a)
print(step)
#[2.   2.25 2.5  2.75 3.  ]
#0.25
ones()

配列の要素を全て1で埋めた配列を生成する

# 5つの1を持つ1次元配列 
print(numpy.ones(5)) 
#[1. 1. 1. 1. 1.] 
# 3行2列の2次元配列 
print(numpy.ones((3, 2))) 
#[[1. 1.] 
#[1. 1.] 
#[1. 1.]]
zeros()

配列の要素を全て0で埋めた配列を生成する

# 5つの0を持つ1次元配列 
print(numpy.zeros(5)) 
# [0. 0. 0. 0. 0.] 

# 3行2列の2次元配列 
print(numpy.zeros((3, 2))) 
#[[0. 0.] 
# [0. 0.] 
# [0. 0.]]
eye()

配列の主対角成分が1となる配列を生成するー単位行列

print(numpy.eye(2)) 
#[[1. 0.] 
# [0. 1.]]
diag()

1次元配列を与えるとその要素が対角上に並んだ2次元配列を、2次元配列を渡すとその対角要素を1次元配列で返します。

# 1次元配列を与える 
a = numpy.array([2, 4, 6]) 
print(numpy.diag(a)) 
#[[2 0 0] 
#[0 4 0] 
#[0 0 6]] 

# 2次元配列を与える 
a = numpy.array([[2, 4], [6, 8]]) 
print(a) 
#[[2 4] 
#[6 8]] 
print("対角要素を取り出す\n", numpy.diag(a)) 
#対角要素を取り出す #[2 8]

配列の次元と要素数

#次元数 shape属性を調べる 
print("a.shape", a.shape) 
# 要素が4つの1次元配列 

print("b.shape", b.shape) 
# 要素が3つの2次元配列 
# a.shape (4,) 
# b.shape (2, 3) 
#要素数 size属性を調べる 
print("a.size", a.size) 
print("b.size", b.size) 
# a.size 4 
# b.size 6

配列を用いた演算 リストやタプルのときはここで終わりでしたが、NumPy配列は先があります。NumPy配列に定義されているいくつかの演算をここでは見ていきます。

基本的な演算

a = numpy.array([0, 1, 2, 3]) 
#[0 1 2 3]
 
# aの各要素に1を足す 
print(a + 1) 
#[1 2 3 4] 

# aの各要素を2倍する 
a = a * 2 
#[0 2 4 6] 

a = numpy.array([1, 2, 3]) 
b = numpy.array([4, 5, 6]) 
# 配列同士の和 
c = a + b
#[5 7 9] 

# 配列同士の差 
c = a - b 
#[-3 -3 -3]

# 配列同士の積 
c = a * b 
#[ 4 10 18]

# 配列同士の商 
c = a / b 
#[0.25 0.4 0.5]

Numpyの配列は、形状の異なる配列の演算も可能になります(ブロートキャスト)

配列の比較

a = numpy.array([1, 2, 3, 4]) 
b = numpy.array([1, 2, 2, 1]) 
# aとbの`各要素`が等しいか調べる 
# Trueのとき等しい 
print(a == b) 
#[ True True False False] 

# 行列a,bが等しいか調べる(全ての要素が同じかどうか) 
print(numpy.array_equal(a, b)) 
#False 

c = numpy.array([1, 2, 3, 4]) 
print(numpy.array_equal(a, c)) 
#True 

# 配列aとbの各要素に対して、aの要素 > bの要素が成り立つか確認する 
print(a > b) 
#[False False True True]

要素を取り出す

配列のインデックスとスライス リストやタプルの要素へのアクセス方法と同様に、配列の要素を取得することができます。インデックスは0から始まる 2次元配列以上の多次元配列の場合にはインデックスを指定する順番、軸 (axis) について気をつける必要があります。

a = numpy.array([1, 3, 5, 7]) 
# index=1(配列の2番目の要素)を取得する 
print(a[1]) #3 

# 2次元配列 
b = numpy.arange(6).reshape(2, 3) 
print("b=", b) 
print("b.shape=", b.shape) 
#b= [[0 1 2] 
    #[3 4 5]] 

#b.shape= (2, 3) 
# bの0番目の軸(axis)方向の1番目を取り出す
print("b[1]=", b[1]) 
#b[1]= [3 4 5] 
#bの0番目の軸(axis)方向の1番目かつ1番目の軸(axis)方向の1番目を取り出す 
print("b[1,1]=", b[1, 1]) 
#b[1,1]= 4 

#スライスに関してもリスト、タプルと同様に [start:end] を指定します。 
# 配列の1番目から2番目の要素を取り出す 
print(a[1:3]) 
#[3 5] 
# 1番目以降の要素を取り出す 
print(a[1:]) [3 5 7] 

#[::-1] は配列を逆順にします。 
print(a[::-1]) 
#[7 5 3 1] 
#スライスした要素を更新する 
print("before=", a) 
a[2:] = numpy.array([10, 14]) 
print("after=", a) 
#before= [1 3 5 7] 
#after= [ 1 3 10 14] 
#2次元配列の各軸についても同じようにスライスを取り出す 
b = numpy.arange(9).reshape(3, 3) 
print("b =", b) 
#b = [[0 1 2] 
#[3 4 5] 
#[6 7 8]] 
# aの右下2×2を取り出す 
print("b[1:, 1:] =", b[1:, 1:]) 
#b[1:, 1:] = [[4 5] 
#[7 8]] 
#: を使うことで範囲を指定せず全部取り出すことができます。 
b = numpy.arange(6).reshape(2, 3) 
print("b =", b) 
#b = [[0 1 2] 
#[3 4 5]] 
# ここではa[1, :] と a[1] は同じです。 
print("b[1, :] =", b[1, :]) 
print("b[1] =", b[1]) 
#b[1, :] = [3 4 5] 
#b[1] = [3 4 5] 
# 真ん中の列を取り出す 
print("b[:, 1] =", b[:, 1]) 
#b[:, 1] = [1 4] 
#: はNumPy配列独自の記法なので、これまでの list などでは使えないことに気をつけてください。

特殊なインデックス 条件に合う部分だけ取り出す、指定した順番に取り出すといったことができます。 配列の要素の指定に配列を使うことでこれらの機能が利用できる

a = numpy.arange(15) 
print(a) 
#[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] 
# aの各要素が3で割り切れるかどうか (Trueなら割り切れる) 
print(a % 3 == 0) 
#[ True False False True False False True False False True False False True False False] 
#これを mask という変数に代入する 
#mask = (a % 3 == 0) 
print(mask) #[ True False False True False False True False False True False False True False False] 
print(a[mask]) 
#[ 0 3 6 9 12] 

#mask を使わずに [] の中に直接書くこともできます。 
print(a[a % 3 == 0]) #[ 0 3 6 9 12] 
a[mask] = -1 
print(a) 
#インデックスが3の倍数の時、要素の値が-1になる 
#[-1 1 2 -1 4 5 -1 7 8 -1 10 11 -1 13 14] 
#上の例では mask をプログラム的に作成しました。その他に、整数のリスト(インデックスのリスト)を与えることもできます。 
# 偶数リスト 
lst = list(range(0, 15, 2)) 
print("index=", lst) 
#index= [0, 2, 4, 6, 8, 10, 12, 14] 
# 偶数インデックスの要素を取り出す print(a[lst]) 
#[-1 2 4 -1 8 10 -1 14] 
#インデックには list ではなくNumPyの array も与えることができ同じように動きます。 
print(a[numpy.arange(0, 15, 2)]) 
#[-1 2 4 -1 8 10 -1 14]

Numpyの配列に三角関数や対数関数、ネイピア数を適用する

a = numpy.arange(1, 5) 
print(a) 
#[1 2 3 4] 
#tan() 
print(numpy.tan(a)) 
#[ 1.55740772 -2.18503986 -0.14254654 1.15782128] 

#exp() 
print(numpy.exp(a)) 
#[ 2.71828183 7.3890561 20.08553692 54.59815003] 

#log() 
print(numpy.log(a)) 
#[0. 0.69314718 1.09861229 1.38629436]

Numpyの配列の最大、最小

関数 説明
numpy.sum 総和を計算する
numpy.mean 平均を計算する
numpy.median 中央値を計算する
numpy.var 分散を計算する
numpy.std 標準偏差を計算する
numpy.min 最小値を計算する
numpy.max 最大値を計算する
numpy.argmin 最小値となるインデックスを調べる
numpy.argmax 最大値となるインデックスを調べる
a = numpy.array([1, 2, 3, 4]) 
print(a) #[1 2 3 4] 
print("総和", numpy.sum(a))
#総和 10 

print("最大値", numpy.max(a))
#最大値 4 

#集計関数も axis 方向を指定することでその軸方向への集計をすることができます。 デフォルトでは結果は2次元配列の場合次元が1つ減った1次元配列となることに注意してください。 
b = numpy.arange(6).reshape(2, 3) 
print("b=", b) 
print("axis=0", b.sum(axis=0)) 
print("axis=1", b.sum(axis=1)) 
print("total", b.sum()) 
#b= [[0 1 2] 
# [3 4 5]] 

#axis=0 [3 5 7] 
#axis=1 [ 3 12] 

#total 15

Numpyの配列をソートする

a = numpy.array([4, 3, 1, 4, 2]) 
print(a) #[4 3 1 4 2] 
#配列の要素をソートするときは numpy.sort() 関数 を利用します。 
print(numpy.sort(a)) 
#[1 2 3 4 4] 
#numpy.argsort() 関数はソートした結果をインデックスで取得します。 
print(numpy.argsort(a)) #[2 4 1 0 3] 
#先に説明した特殊なインデックスを用いると 
numpy.sort() 関数と同じ結果が得られます。 
mask = numpy.argsort(a) a[mask] 
#array([1, 2, 3, 4, 4])