はじめに #
NumPy配列のコピーや次元の結合、結合・分割、ソートについて。
環境 #
- NumPy 1.19
配列のコピー #
=でコピーすると、コピー元とコピー先で同じオブジェクトを参照するため、 どちらかを操作するともう片方も変更される (Shallow copy)。 一方、copyメソッドでコピーすると、コピー先で新たにオブジェクトを作成するため、 どちらかを操作しても、もう片方には反映されない (Deep copy)。
>>> import numpy as np
>>> a = np.array([1,2,3])
>>> b=a # Shallow copy
>>> b[0]=4
>>> b
array([4, 2, 3])
>>> a
array([4, 2, 3]) # aも変更される
>>> c=a.copy() # Deep copy
>>> c[0]=5
>>> c
array([5, 2, 3])
>>> a
array([4, 2, 3]) # aは変更されない
サイズ・次元の変更 #
reshapeを使うと、指定したサイズに変形された配列が返される。 ただし、元の配列のサイズは変更されない。 行数または列数の片方のみを指定するときは、 指定しない次元の要素数を-1とすると、自動で変形してくれる。 また、flattenを使うと、2次元配列を1次元配列に変換できる。 こちらも元の配列のサイズは変更されない。
>>> a = np.array([[1,2,3],
... [4,5,6]]) # 2x3行列
>>> a.reshape([3,2]) # 3x2行列に変形。ビューを返す。
array([[1, 2],
[3, 4],
[5, 6]])
>>> a.reshape([3,-1]) # サイズを指定しない次元を-1とすると、自動的に変形してくれる
array([[1, 2],
[3, 4],
[5, 6]])
>>> a.flatten() # 1次元配列を作成
array([1, 2, 3, 4, 5, 6])
>>> a.flatten() # 1次元配列に変換
array([1, 2, 3, 4, 5, 6])
>>> a # aのサイズは変わらない
array([[1, 2, 3],
[4, 5, 6]])
結合 #
2つのNumPy配列を1つのNumPy配列に結合する。
関数 | 記法 | 説明 |
---|---|---|
vstack | np.vstack([a,b]) | 縦(0軸)方向に結合 |
hstack | np.hstack([a,b]) | 横(1軸)方向に結合 |
dstack | np.dstack([a,b]) | 深さ(2軸)方向に結合 |
concatenate | np.concatenate([a,b], axis=0) | 指定した軸方向に結合 |
>>> a = np.array([[0,1],
... [2,3]])
>>> b = np.array([[4,5],
... [6,7]])
>>> np.hstack([a,b])
array([[0, 1, 4, 5],
[2, 3, 6, 7]])
>>> np.vstack([a,b])
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
>>> np.concatenate([a,b],axis=0)
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
>>> np.concatenate([a,b],axis=1)
array([[0, 1, 4, 5],
[2, 3, 6, 7]])
分割 #
NumPy配列を分割する。分割された配列はリスト形式で返される。
関数 | 記法 | 説明 |
---|---|---|
vsplit | np.vsplit(a,n) | 縦(0軸)方向に結合・分割 |
hsplit | np.hsplit(a,n) | 横(1軸)方向に結合・分割 |
dsplit | np.dsplit(a,n) | 深さ(2軸)方向に結合・分割 |
split | np.split(a, axis=0) | 指定した軸方向に結合・分割 |
nは、整数またはリストである。 nが整数の場合、配列はn個に均等分割される。 そのため、nは分割したい軸方向の配列の要素数の約数でなければならない。
>>> a=np.arange(16.0).reshape(4, 4)
>>> a
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[ 12., 13., 14., 15.]])
>>> np.vsplit(a,2) # 2つに均等分割
[array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.]]),
array([[ 8., 9., 10., 11.],
[ 12., 13., 14., 15.]])]
>>> np.vsplit(a,4) # 4つに均等分割
[array([[ 0., 1., 2., 3.]]),
array([[ 4., 5., 6., 7.]]),
array([[ 8., 9., 10., 11.]]),
array([[ 12., 13., 14., 15.]])]
また、nをリストにすることで、分割する位置を指定できる。 リストは昇順にソートされた整数からなる。
>>> np.vsplit(a,[3]) # 3行目で分割
[array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]]),
array([[ 12., 13., 14., 15.]])]
>>> np.vsplit(a,[1,2]) # 1, 2行目で分割
[array([[ 0., 1., 2., 3.]]),
array([[ 4., 5., 6., 7.]]),
array([[ 8., 9., 10., 11.],
[ 12., 13., 14., 15.]])]
ソート #
配列をソートするには、sort関数を使う。 ただし、昇順のソートしかできないため、降順にソートした結果が欲しい場合はスライスなどを使う必要がある。 1次元配列の場合。
>>> a = np.array([1,3,5,2,4]) # 1次元配列の場合
>>> np.sort(a) # 昇順にソート
array([1, 2, 3, 4, 5])
>>> np.sort(a)[::-1] # 降順にソートする場合は、スライスを使う
array([5, 4, 3, 2, 1])
2次元配列の場合。 必要に応じてソートする次元を指定する。
>>> b=np.array([[1,3,5], # 2次元配列の場合
[6,4,2]])
>>> np.sort(b) # デフォルトでは最大次元の軸に沿ってソート
array([[1, 3, 5],
[2, 4, 6]])
>>> np.sort(b, axis=0) # axisでソートする軸を指定
array([[1, 3, 2],
[6, 4, 5]])
>>> np.sort(b, axis=None) # axis=Noneで1次元配列にして返す
array([1, 2, 3, 4, 5, 6])