工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

numpy自分用覚書

自分用numpyメモ。

import numpy as np
x = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

スライス

>>> z = np.arange(0, 10)
  • z[start:stop]

start番要素からstop-1番要素まで。

>>> z[3:5]
array([3, 4])
  • z[start:stop:step]
>>> z[3:7:2]
array([3, 5])
  • z[start::step]

指定しなければ、先頭または末尾。

>>> z[3::1]
array([3, 4, 5, 6, 7, 8, 9])

keepdims

配列の次元数を保持する。

>>> y1 = np.sum(x, axis=1, keepdims=True)
>>> y1
>>> array([[ 6],
           [15],
           [24]])
>>> y2 = np.sum(x, axis=1)
>>> y2
>>> array([ 6, 15, 24])


reshapeの引数に-1を指定

自動的に、要素数を計算してくれる。当たり前だが、2つ以上指定してはだめ。

>>> x2 = x.reshape(1, -1)
>>> x2
array([[1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> x3 = x.reshape(-1, 1)
>>> x3
array([[1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
>>> x4 = x.reshape(-1)
>>> x4
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x5 = x.reshape(-1, -1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: can only specify one unknown dimension

dot

ベクトルの内積または行列の積を計算する。内積はドット記号を使うので、dotという名前の関数になっていると思われる。通常の * は、要素同士の積(アダマール積)。

>>> y = np.dot(x[0], x[:, 0])
>>> y
30
>>> y = np.dot(x, x)
>>> y
array([[ 30,  36,  42],
       [ 66,  81,  96],
       [102, 126, 150]])

pad

ある値でパディングを行う。第2引数でパディングのサイズ、形状を指定。

全次元の先頭、末尾に同じだけパディング。

>>> np.pad(x, 2, "constant", constant_values=1)
array([[1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 2, 3, 1, 1],
       [1, 1, 4, 5, 6, 1, 1],
       [1, 1, 7, 8, 9, 1, 1],
       [1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1]])
  • 1つのタプルを指定

各次元の先頭と末尾に対応。

>>> np.pad(x, (1,2), "constant", constant_values=1)
array([[1, 1, 1, 1, 1, 1],
       [1, 1, 2, 3, 1, 1],
       [1, 4, 5, 6, 1, 1],
       [1, 7, 8, 9, 1, 1],
       [1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1]])
  • 2つのタプルのリストを指定

リスト要素が各次元に対応。タプルの要素順はその次元の先頭、末尾パディングサイズに対応。 np.pad(x, [(0,0), (0,0), (pad, pad), (pad, pad)], "constant", constant_values=1)

>>> np.pad(x, [(0,2), (1,3)], "constant", constant_values=1)
array([[1, 1, 2, 3, 1, 1, 1],
       [1, 4, 5, 6, 1, 1, 1],
       [1, 7, 8, 9, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1]])

repeat

繰り返し同じ要素の配列生成する

>>> x.repeat(3, axis=0)
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [4, 5, 6],
       [4, 5, 6],
       [4, 5, 6],
       [7, 8, 9],
       [7, 8, 9],
       [7, 8, 9]])
>>> x.repeat(3, axis=1)
array([[1, 1, 1, 2, 2, 2, 3, 3, 3],
       [4, 4, 4, 5, 5, 5, 6, 6, 6],
       [7, 7, 7, 8, 8, 8, 9, 9, 9]])

random

np.random.permutation

ランダムに並べて返す

# 整数をランダムに並べて返す
>>> np.random.permutation(10)
array([9, 1, 5, 8, 3, 0, 4, 7, 2, 6])

# 配列aをランダムに並べて返す
>>> a = [1,2,3,4,5,6]
>>> np.random.permutation(a)
array([3, 4, 6, 2, 1, 5])

np.random.choice

指定した数だけランダムに選んで返す 標準モジュールrandomのchoiceとは引数構成が違うので注意。

# aは1次元のシーケンス(配列)とする

# aから1つの要素を選択
np.random.choice(a)

# aから2個選択
np.random.choice(a, size=2)
# (2,3)のタプルが返り値
np.random.choice(a, size=(2,3))

# 重複有無(replace)
np.random.choice(a, size=3, replace=True) # 重複あり
np.random.choice(a, size=3, replace=False) # 重複なし

# 選択確率(p)
# 長さがaと同じで合計1となるリストにすること
np.random.choice(a, 3, replace=False, p=[0.1, 0.1, 0.3, 0.3, 0.1, 0.1])

empty

配列を初期化せずに確保する。

# np.empty(shape, dtype=float)
>>> np.empty((3,3))
array([[0.000e+000, 0.000e+000, 0.000e+000],
       [0.000e+000, 0.000e+000, 1.877e-321],
       [0.000e+000, 0.000e+000, 0.000e+000]])
>>> np.empty((3,3), dtype=np.int32)
array([[1697542254, 2037674093,  741550120],
       [ 539765043, 1887007844, 1886272869],
       [1953392942,  220803635,         10]])

zeros_like

引数の配列と同じ形のゼロ配列を作る。

>>> a
array([[0.3720223 , 0.49858174, 0.79575115],
       [0.32627888, 0.57125729, 0.25105339],
       [0.32911995, 0.5271041 , 0.78931682]])
>>> np.zeros_like(a)
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])