numpyの関数
pythonndarrayの生成
ndarrayはnumpyの多次元の配列を表すオブジェクトで、[start:stop:step, …]の indexでアクセスできる。
x = np.array([[1, 2, 3, 4], [2, 4, 6, 8]])
print(x[0, 1]) # 2
print(x[0,1:-1]) # [2 3]
print(x[:,2]) # [3 6]
print(x[:,::2]) # [[1 3] [2 6]]
print(x[1,::-1]) # [8 6 4 2]
arrayやiteratableオブジェクトからndarrayを生成する。
print(np.array([1, 2, 3])) # [1 2 3]
def generate():
for x in range(3):
yield x
x = np.fromiter(generate(), dtype=float)
print(x) # [ 0. 1. 2.]
引数で渡したshapeを特定の値で埋めたndarrayを生成する。
print(np.zeros(5)) # [ 0. 0. 0. 0. 0.]
print(np.ones((2,2))) # [[ 1. 1.] [ 1. 1.]]
print(np.full((2, 3), 2)) # [[2 2 2] [2 2 2]]
Python built-inのrange()のndarray版と、startからstopまで等間隔なndarrayを生成する関数。
print(np.arange(5)) # [0 1 2 3 4]
print(np.linspace(2.0, 3.0, num=5)) # [ 2. 2.25 2.5 2.75 3. ]
diagonal(対角)は1,それ以外は0の単位行列を生成する。
print(np.identity(3)) # [[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]]
print(np.eye(3)) # [[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]]
- random.random():
[0.0, 1.0)
で連続一様分布 - random.randint():
[low, high)
で離散一様分布 - random.uniform():
[low, high)
で連続一様分布
ランダム値のndarrayを生成する。
print(np.random.random((2, 2)) # [[ 0.84157926 0.77701369] [ 0.92937916 0.41447905]]
print(np.random.randint(low=5, high=10, size=(2, 2))) # [[9 5] [7 7]]
print(np.random.uniform(low=5, high=10, size=(2,2))) # [[ 9.72222125 6.07259325] [ 7.24174366 9.27801853]]
加工
キャストする。
print(np.array([1, 2, 2.5]).astype(int)) # [1 2 2]
shapeを変更するのと、1次元にする関数。
x = np.arange(4).reshape((2, 2))
print(x) # [[0 1] [2 3]]
print(x.flatten()) # [0 1 2 3]
paddingする。modeで埋まる値が決まる。
from math import ceil
def padding_to(array, width, height):
return np.pad(array, pad_width=(
(int((height-array.shape[0])/2), int(ceil((height-array.shape[0])/2))),
(int((width-array.shape[1])/2), int(ceil((width-array.shape[1])/2)))),
mode='constant', constant_values=0)
print(padding_to(np.array([[2, 4], [6, 8]]), 8, 5))
"""
[[0 0 0 0 0 0 0 0]
[0 0 0 2 4 0 0 0]
[0 0 0 6 8 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]]
"""
print(np.pad(np.arange(9).reshape(3,3), pad_width=1, mode='edge'))
"""
[[0 0 1 2 2]
[0 0 1 2 2]
[3 3 4 5 5]
[6 6 7 8 8]
[6 6 7 8 8]]
"""
対角の値を返したり、対角行列にしたりする。
x = np.arange(9).reshape((3,3))
print(np.diag(x)) # [0 4 8]
print(np.diag(np.diag(x))) # [[0 0 0] [0 4 0] [0 0 8]]
print(np.diag(np.diag(np.diag(x)))) # [0 4 8]
print(np.diagonal(x)) # [0 4 8]
print(np.diagonal(np.diagonal(x))) # diag requires an array of at least two dimensions
ソートとシャッフル。argsort()とargpartition()はindexを返す。 argpartition()はkth番目の値で分けるもの(下の例だと4番目に小さいindex 0)で、パーティション内の順序は保証されないが、n番目のindexだけ欲しい場合はargsort()より速い。 random.permutation()はPandasの行をシャッフルするときにも使える。
x = np.random.random((3, 3))
print(np.sort(x))
"""
[[ 0.14366067 0.41558783 0.7584969 ]
[ 0.1395897 0.78905376 0.89709119]
[ 0.3235212 0.82675995 0.95140141]]
"""
x2 = np.array([3, 1, 2, 1, 4, 5])
print(np.argsort(x2)) # [1 3 2 0 4 5]
print(np.argpartition(x2, 3)) # [3 2 1 0 4 5]
print(np.random.permutation(np.arange(5))) # [3 1 0 4 2]
repeat()は各値を繰り返し、tile()は敷き詰める。unique()はユニークな値にする。
x = np.arange(4).reshape(2,2)
print(np.repeat(x, 2)) # [0 0 1 1 2 2 3 3]
print(np.repeat(x, 2, axis=1)) # [[0 0 1 1] [2 2 3 3]]
print(np.tile(x, (3,2)))
"""
[[0 1 0 1]
[2 3 2 3]
[0 1 0 1]
[2 3 2 3]
[0 1 0 1]
[2 3 2 3]]
"""
x2 = np.repeat([np.repeat(np.arange(3), 2)], 2, axis=0)
print(x2) # [[1 1 2 2 3 3] [1 1 2 2 3 3]]
print(np.unique(x2)) # [1 2 3]
ローリングする。
print(np.roll(np.arange(8).reshape(4, 2), 2, axis=0)) # [[4 5] [6 7] [0 1] [2 3]]
縦横に結合する。
x = np.arange(4).reshape((2, 2))
y = np.identity(2)
print(np.vstack((x, y)))
'''
[[ 0. 1.] [ 2. 3.]
[ 1. 0.] [ 0. 1.]]
'''
print(np.hstack((x, y)))
'''
[[ 0. 1. 1. 0.]
[ 2. 3. 0. 1.]]
'''
分割する。array_split()はちょうど分けられなくてもエラーにしない。
print(np.split(np.arange(7), 3)) # ValueError: array split does not result in an equal division
print(np.array_split(np.arange(7),3)) # [array([0, 1, 2]), array([3, 4]), array([5, 6])]
座標の値からndarrayを生成する。
x, y = np.meshgrid(np.linspace(0,1,5), np.linspace(0,1,5))
print(x)
'''
[[ 0. 0.25 0.5 0.75 1. ]
[ 0. 0.25 0.5 0.75 1. ]
[ 0. 0.25 0.5 0.75 1. ]
[ 0. 0.25 0.5 0.75 1. ]
[ 0. 0.25 0.5 0.75 1. ]]
'''
print(y)
'''
[[ 0. 0. 0. 0. 0. ]
[ 0.25 0.25 0.25 0.25 0.25]
[ 0.5 0.5 0.5 0.5 0.5 ]
[ 0.75 0.75 0.75 0.75 0.75]
[ 1. 1. 1. 1. 1. ]]
'''
uint8のndarrayをバイナリの値に変換するのと、その逆。
x = np.unpackbits(np.array([[8], [23]], dtype=np.uint8), axis=1)
print(x) # [[0 0 0 0 1 0 0 0] [0 0 0 1 0 1 1 1]]
print(np.packbits(x, axis=1)) # [[ 8] [23]]
比較
0でないindexを返す。booleanのndarrayからTrueを抽出するのにも使える。 where()の第1引数は条件式で、第2引数と第3引数を渡すとそれぞれTrueとFalseの場合に置換される。
x = np.array([[1,0,0], [0,2,0], [1,1,0]])
print(np.nonzero(x)) # (array([0, 1, 2, 2]), array([0, 1, 0, 1])) => [0, 0], [1, 1], [2, 0], [2, 1]
print(np.where(x)) # (array([0, 1, 2, 2]), array([0, 1, 0, 1]))
print(x[np.nonzero(x)]) # [1 2 1 1]
print(x > 1) # [[False False False] [False True False] [False False False]]
print(x[np.nonzero(x > 1)]) # [2]
print(np.where(x == 1, x, 0)) # [[1 0 0] [0 0 0] [1 1 0]]
一致する場合はTrueを返す。allclose()は誤差を許容する。
x = [1e10,1e-8]
y = [1.00001e10,1e-9]
print(x == y) # False
print(np.allclose(x, y)) # True
print(np.array_equal(x, y)) # False
o = np.ones(3)
o2 = np.ones(4)
print(o == o2) # comparison failed
print(np.array_equal(o, o2)) # False
和、積、差集合と排他的論理和。
x = [1, 3, 4, 3]
y = [3, 1, 2, 1]
print(np.union1d(x, y)) # [1 2 3 4]
print(np.intersect1d(x, y)) # [1 3]
print(np.setdiff1d(x, y)) # [4]
print(np.setxor1d(x, y)) # [2 4]
AND,OR,NOT,XORしたbooleanの値を返す。all()とany()はarrayに対するANDとOR。
x = [True, False, True]
y = [False, False, True]
print(np.logical_and(x, y)) # [False False True]
print(np.all([x, y, np.repeat([True], 3)], axis=0)) # [False False True]
print(np.logical_or(x, y)) # [ True False True]
print(np.any([x, y, np.repeat([True], 3)], axis=0)) # [ True True True]
print(np.logical_not(x)) # [False True False]
print(np.logical_xor(x, y)) # [ True False False]
正数の出現回数をカウントする。
print(np.bincount([0, 1, 2, 1, 2, 6, 1])) # [1 3 2 0 0 0 1]
計算
和と内積(a・b)。和は+でも計算できるが、通常のarrayに使うと後ろに結合されてしまうのに注意。 “@“はmatmul()と同じで数値との積は計算できない。 “*“はmultiply()で、要素ごとの積が返る。
x = np.arange(4).reshape((2, 2))
print([0, 1, 2] + [1, 2, 3]) # [0, 1, 2, 1, 2, 3]
print(x + x) # [[0 2] [4 6]]
print(np.add(x, x)) # [[0 2] [4 6]]
print(np.dot(np.ones((2,2)), np.ones((2,3)))) # [[ 2. 2. 2.] [ 2. 2. 2.]]
print(np.matmul(np.ones((2,2)), np.ones((2,3)))) # [[ 2. 2. 2.] [ 2. 2. 2.]]
print(np.ones((2,2)) @ np.ones((2,3))) # [[ 2. 2. 2.] [ 2. 2. 2.]]
print(np.ones((2,2)) * np.ones((2,3))) # operands could not be broadcast together with shapes (2,2) (2,3)
print(np.dot(np.ones((2,2)), 2)) # [[ 2. 2.] [ 2. 2.]]
print(np.matmul(np.ones((2,2)), 2)) # Scalar operands are not allowed, use '*' instead
print(np.ones((2,2)) @ 2) # Scalar operands are not allowed, use '*' instead
平方根を返す。emathの方は複素数が返る。
print(np.sqrt([4, 0, -4])) # [ 2. 0. nan]
print(np.emath.sqrt([4, 0, -4])) # [ 2.+0.j 0.+0.j 0.+2.j]
三角関数と逆三角関数。
from math import pi
x = np.linspace(-pi, pi, num=5)
print(np.sin(x)) # [ -1.22464680e-16 -1.00000000e+00 0.00000000e+00 1.00000000e+00 1.22464680e-16]
print(np.cos(x)) # [ -1.00000000e+00 6.12323400e-17 1.00000000e+00 6.12323400e-17 -1.00000000e+00]
print(np.tan(x)) # [ 1.22464680e-16 -1.63312394e+16 0.00000000e+00 1.63312394e+16 -1.22464680e-16]
x2 = np.linspace(-1, 1, num=5)
print(np.arcsin(x2)) # [-1.57079633 -0.52359878 0. 0.52359878 1.57079633]
print(np.arccos(x2)) # [ 3.14159265 2.0943951 1.57079633 1.04719755 0. ]
print(np.arctan(x2)) # [-0.78539816 -0.46364761 0. 0.46364761 0.78539816]
指数と、eが底の自然対数(ln(x))。
x = [0.1, 1, 2]
print(np.exp(x)) # [ 1.10517092 2.71828183 7.3890561 ]
print(np.log(x)) # [-2.30258509 0. 0.69314718]
minより小さな値はminに、maxより大きな値はmaxにする。log()の引数に0が渡るのを避けることができる。
x = np.arange(2)
np.log(x) # RuntimeWarning: divide by zero encountered in log
x2 = np.clip(x, 1e-10, x)
print(x2) # [ 1.00000000e-10 1.00000000e+00]
np.log(x2) # ok
最小、最大、合計、平均。argmin()とargmax()はindexを返し、average()は重みを付けられる。average以外はx.min()のように呼ぶこともできる。
x = np.arange(4).reshape((2, 2))
print(np.min(x)) # 0
print(np.max(x)) # 3
print(np.argmax(x)) # 3
print(np.sum(x)) # 6
print(np.mean(x)) # 1.5
print(np.average(x, weights=np.array([[0, 1], [4, 1]]))) # 2.0 <= (1 * 1 + 2 * 4 + 3 * 1) / (1 + 4 + 1)
累積和と前の値との差。
x = np.arange(9).reshape((3, 3))
print(np.cumsum(x, axis=1)) # [[ 0 1 3] [ 3 7 12] [ 6 13 21]]
print(np.diff(x, axis=1)) # [[1 1] [1 1] [1 1]]
切り上げ、切り捨てと絶対値。floor(-2.5)は-3.0になり、trunc(-2.5)は-2.0になる。
copysign()は第2引数の符号を第1引数にコピーする。
exercisesではnp.copysign(np.ceil(np.abs(Z)), Z)
のようにabsしてから元に戻すために使われていた。
x = np.random.uniform(low=-5, high=5, size=(2,2))
print(x) # [[ 2.19861752 -4.22997748] [ 0.15346107 0.62893343]]
print(np.ceil(x)) # [[ 3. -4.] [ 1. 1.]]
print(np.floor(x)) # [[ 2. -5.] [ 0. 0.]]
print(np.trunc(x)) # [[ 2. -4.] [ 0. 0.]]
print(np.abs([-2, 0, 2])) # [2 0 2]
print (np.copysign([1, -2, -1], [-2, 1, -1])) # [-1. 2. -1.]
行列式(determinant)を計算する。
print(np.linalg.det(np.arange(4).reshape((2, 2)))) # -2.0 <= 0 * 3 - 1 * 2
パーセンタイルを返す。
print(np.percentile(np.arange(16).reshape((4,4)), 90)) # 13.5
1次元の畳み込み。第2引数をずらしながら掛けていく。 畳み込みニューラルネットワークでも使う2次元の畳み込みの関数はnumpyにはないが、scipyのsignal.convolve2d()が使える。
TensorFlow チュートリアル2(Deep MNIST for Experts) - sambaiz-net
print(np.convolve([3, 6, 9], [0, 1, 0.5])) # [0. 1. 2.5 4. 1.5] <= [(0*3), (0*6+1*3), (0*9+1*6+0.5*3), (1*9+0.5*6), (0.5*9)]
from scipy import signal
print(signal.convolve2d(np.arange(9).reshape((3,3)), np.eye(2)))
'''
[[ 0. 1. 2. 0.]
[ 3. 4. 6. 2.]
[ 6. 10. 12. 5.]
[ 0. 6. 7. 8.]]
'''
その他
その前の関数でreduceする。
x = np.arange(4).reshape((2,2))
print(np.add.reduce(x)) # [2 4] <= default axis value is 0
print(np.add.reduce(x, axis=1)) # [1 5]
ランダムに選ぶ。選ばれる確率pを渡すことができる。
x = np.arange(5)
print(np.random.choice(x, 10)) # [3 3 0 4 1 2 0 4 2 1]
print(np.random.choice(x, 10, p=(x / np.sum(x)))) # [3 4 3 4 3 1 3 1 3 3]
フラットなindexをそのshapeでのindexに変換する。
x = np.arange(9).reshape(3,3)
idx = np.unravel_index(5, x.shape)
print(idx) # (1, 2)
print(x[idx]) # 5
線形補間(interpolation)した値を返す。
x = np.arange(100)
y = np.sin(0.1 * x)
x2 = [10.5, 20.2, 30.4, 60.3, 80.9]
y2 = np.interp(x2, x, y)
import matplotlib.pyplot as plt
plt.plot(x, y)
plt.plot(x2, y2, 'o')
plt.show()