Helve’s Python memo

Pythonを使った機械学習やデータ分析の備忘録

<NumPy> 配列の作成

NumPyを使った、基本的な配列や線形代数学でよく使われる配列の生成について。

目次

基本的な配列の作成

NumPyは、ベクトルや行列の計算を効率良く行うためのモジュールである。
初めに、以下のコマンドを入力してNumPyを取り込む。
as以下に npと入力すると、NumPyをnpと短縮して呼び出せる。

>>> import numpy as np

配列の中身を自分で指定して作成する場合、 np.array()メソッドを用いる。
np.array()は、引数にPythonのリストをとる。
リストを重ねる(ネストする)ことで、2次元や3次元の配列を作成できる。

>>> a = np.array([1,2,3])                       # 1次元配列
>>> a
array([1, 2, 3])
>>> b = np.array([[1,2,3],[4,5,6]])             # 2次元配列
>>> b
array([[1, 2, 3],
       [4, 5, 6]]) 
>>> c = np.array([[[1,2],[3,4]],[[5,6],[7,8]]]) # 3次元配列
>>> c
array([[[1, 2],
        [3, 4]],

       [[5, 6],
        [7, 8]]])

線形代数学でよく使われる配列の生成

全要素が0の配列

全要素が0の配列を作成する場合、np.zeros()メソッドや np.zeros_like()メソッドを用いる。
np.zeros()メソッドの場合、引数に整数をとると、 その整数の数だけ0要素を持つ1次元の配列が作られる。 また、引数に整数のリストをとると、2次元以上の0配列が作られる。
一方、np.zeros_like()メソッドの場合、 引数に他のNumPy配列をとり、その配列と同じ形の0配列が作られる。

>>> np.zeros(3)           # 1次元の配列
array([ 0.,  0.,  0.])
>>> np.zeros([2,3])       # 2次元の配列
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
>>> b = np.array([[1, 2, 3],
...               [4, 5, 6]])
>>> np.zeros_like(b)      # 他の配列と同じサイズの配列
array([[0, 0, 0],
       [0, 0, 0]])

全要素が1の配列

全要素が1の配列を作成する場合、np.ones()メソッドや np.ones_like()メソッドを用いる。
配列の作成方法は、それぞれnp.zeros(), np.zeros_like()メソッドに同じ。

>>> np.ones(3)           # 1次元の配列
array([ 1.,  1.,  1.])
>>> np.ones([2,3])       # 2次元の配列
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> b = np.array([[1, 2, 3],
...               [4, 5, 6]])
>>> np.ones_like(b)      # 他の配列と同じサイズの配列
array([[1, 1, 1],
       [1, 1, 1]])

全要素が同じ値の配列

全要素が同じ値の配列を作成する場合、np.full()メソッドや np.full_like()メソッドを用いる。
np.full()メソッドは引数を2つとり、 第1引数で配列の形を、第2引数で配列の値を指定する。 2次元以上の配列を作成したい場合、第1引数がリストにする。
また、np.full_like()メソッドは、 第1引数に他のNumPy配列、第2引数に値をとる。 第1引数の配列と同じ形かつ、全要素が第2引数と同じ値の配列が作成される。

>>> np.full(3, 10)       # 1次元の配列
array([10, 10, 10])
>>> np.full([2,2], 10)   # 2次元の配列
array([[ 10.,  10.],
       [ 10.,  10.]])
>>> b = np.array([[1, 2, 3],
...               [4, 5, 6]])
>>> np.full_like(b, 10)  # 他の配列と同じサイズの配列
array([[10, 10, 10],
       [10, 10, 10]])

単位行列など

単位行列を作成する場合、np.identity()メソッドまたは np.eye()メソッドを用いる。
np.identity()メソッドの場合、 引数として与えた整数の大きさの単位行列が作成される。
また、np.eye()メソッドの場合、 引数に整数を1つだけ与えると、np.identity()と同様に単位行列が作成される。 一方、引数をnp.eye(n, m)のように2つ与えると、主対角成分が1のn×m行列が作成される。 さらに、引数kで値が1となる対角を指定できる。

>>> np.identity(3)        # 単位行列
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> np.eye(3)             # 単位行列(引数が1個の場合)
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> np.eye(2, 3)          # 主対角が1, それ以外が0の3x2行列
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])
>>>
>>> 1となる対角をkで指定(k>0は主対角より上、k<0は主対角より下)
>>> np.eye(4, 5, k=1)  
array([[ 0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  1.]])

三角行列など

三角行列は、主対角より「上」または「下」の成分が全て0である正方行列である。
np.tri()メソッドを用いると、下三角行列を作成できる。 引数に整数を1つ与えると、その整数の大きさの正方行列になる。 引数にnp.tri(n, m)のように整数を2つ与えると、 主対角より上が0となるn×m行列が作成される。 また、引数kでどの対角から上が0となるか指定できる。

>>> np.tri(3)
array([[ 1.,  0.,  0.],
       [ 1.,  1.,  0.],
       [ 1.,  1.,  1.]])
>>> np.tri(3,5)
array([[ 1.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  0.,  0.]])
>>> np.tri(3,5,k=-1)  # k>0は主対角より上の対角、k<0は主対角より下の対角
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  0.,  0.,  0.]])

また、他の配列に対して、三角部分の要素を0とした配列を得るためには、 np.tril()メソッドまたは np.triu()メソッドを用いる。 それぞれ、引数にとった行列の上三角部分と下三角部分を0とした行列を返す。 また、引数kで0とする対角を指定できる。

>>> b = np.array([[1,2,3],[4,5,6]])
>>> b
array([[1, 2, 3],
       [4, 5, 6]])
>>> np.tril(b)        # 行列の下三角部分
array([[1, 0, 0],
       [4, 5, 0]])
>>> np.tril(b, k=-1)  # kで0とする対角を指定(デフォルトはk=0: 主対角)
array([[0, 0, 0],
       [4, 0, 0]])
>>> np.triu(b)        # 行列の上三角部分
array([[1, 2, 3],
       [0, 5, 6]])

その他の特殊な配列の作成

線形に等間隔な1次元配列

>>> np.arange(1,10)    # 区間[1, 10)の整数
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(1,10,2)  # 区間[1, 10)の整数を2刻みで
array([1, 3, 5, 7, 9])
>>> np.linspace(2,3,5) # 線形に等間隔な区間[2, 3]の数を5個
array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ])

対数的に等間隔な1次元配列

>>> np.logspace(1, 2, 5) # 10^1から10^2まで対数的に等間隔な5個の配列
array([ 10.        ,  17.7827941 ,  31.6227766 ,  56.23413252,
       100.        ])
>>> np.logspace(1, 5, 5, base=2) # baseで対数の底を指定
array([ 2.,  4.,  8., 16., 32.])

ランダムな要素を持つ配列

numpy.randomモジュールを使用する。

>>> np.random.seed(0)
>>> # シード値(非負の整数)を設定すると、常に一定順序で乱数列が発生
>>> np.random.rand(2,3)      # 区間[0, 1)で一様分布
array([[0.5488135 , 0.71518937, 0.60276338],
       [0.54488318, 0.4236548 , 0.64589411]])
>>> np.random.randn(2, 3)    # 正規分布(平均0, 分散1)
array([[ 0.95008842, -0.15135721, -0.10321885],
       [ 0.4105985 ,  0.14404357,  1.45427351]])
>>> np.random.randint(10)    # 区間[0, 10)で均等分布の整数(引数1つの場合)
8
>>> np.random.randint(5, 10) # 区間[5, 10)で均等分布の整数(引数2つの場合)
6
>>> np.random.randint(5, 10, size=(2, 4)) # sizeオプションで配列サイズを指定
array([[6, 5, 6, 9],
       [8, 5, 8, 5]])