JavaScriptを有効にしてください

NumPy配列の操作

 ·   3 min read

はじめに

NumPy配列のコピーや次元の結合、結合・分割、ソートについて。

環境

ソフトウェア バージョン
NumPy 1.19

配列のコピー

=でコピーすると、コピー元とコピー先で同じオブジェクトを参照するため、
どちらかを操作するともう片方も変更される (Shallow copy)。
一方、copyメソッドでコピーすると、コピー先で新たにオブジェクトを作成するため、
どちらかを操作しても、もう片方には反映されない (Deep copy)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
>>> 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次元配列に変換できる。 こちらも元の配列のサイズは変更されない。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
>>> 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])
1
2
3
4
5
>>> 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) 指定した軸方向に結合
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
>>> 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は分割したい軸方向の配列の要素数の約数でなければならない。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
>>> 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をリストにすることで、分割する位置を指定できる。 リストは昇順にソートされた整数からなる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> 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次元配列の場合。

1
2
3
4
5
>>> 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次元配列の場合。 必要に応じてソートする次元を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> 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])

参考リンク

Array manipulation routines — NumPy v1.19 Manual
Quickstart tutorial — NumPy v1.19 Manual

シェアする

Helve
WRITTEN BY
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

サイト内検索