多次元配列
ファイル
|
NumPy多次元配列 (ndarray)
ここでは,Python の NumPy の多次元配列 (ndarray) について説明します.これは Numpy の基本的なデータ保持形式なので,ndarray の理解を避けては NumPy を使いこなせません.以下が,本ページの内容です.
目次
多次元配列「ndarray」とは
特徴
ndarray は Numpy で使われる多次元配列です.これは一般的なコンパイラー言語,例えば C++ の配列(もちろん多次元)と似たところがあります.ndarray の特徴は,次のとおりです.
- 配列の要素のアクセスには整数のインデックスを使う.
- 全ての要素のデータの型は同一である (要素毎のメモリーサイズが同一).
- データは,メモリーの連続した領域に格納される.
このようにすることで,データに高速にアクセスすることができます.大規模なデータを取り扱うことが多い数値計算では,「データへの高速アクセス」は極めて重要です.
一方,元々 Python に備わっているリストでは,要素のデータの型は同一である必要はありません.型を気にせずにプログラムを書くことができる反面,データへの高速アクセスができなくなります.データの型が異なれば,メモリサーズが異なるためです.したがって,メモリーの連続した領域へのデータの格納ができなくなります (可能かもしれないが難しい).すると,要素へのアクセスに時間がかかるようになり,高速の演算には不向きなデータの保持方法と言えます.
具体例
以下に具体例を示します.非常に単純な例なので,およその動作は想像できると思います.003 – 014 行で三次元の配列を作成します.リストを numpy.array() で ndarray の配列オブジェクトに変換します.3×3×3 の配列です.016 で出来上がったオブジェクトのクラスを確認します.このオブジェクは,<numpy.ndarray>です.017行で配列の次元,018行で構造を表示します.019 – 021 行で配列の要素を表示します.結果を見れば,理解できるでしょう.
ndarray の具体例 |
実行結果 |
001 import numpy as np
002
003 a = np.array([[\
004 [ 0, 1, 2],\
005 [ 10, 11, 12],\
006 [ 20, 31, 32]],\
007 [\
008 [100, 101, 102],\
009 [110, 111, 112],\
010 [120, 121, 122]],\
011 [\
012 [200, 201, 202],\
013 [210, 211, 212],\
014 [220, 221, 222]]])
015
016 print('type: ',type(a))
017 print('dim: ', a.ndim)
018 print('shape: ', a.shape)
019 print('a[1]: ', a[1])
020 print('a[1][2]: ', a[1][2])
021 print('a[1][2][0]: ', a[1][2][0])
|
type: <class 'numpy.ndarray'>
dim: 3
shape: (3, 3, 3)
a[1]: [[100 101 102]
[110 111 112]
[120 121 122]]
a[1][2]: [120 121 122]
a[1][2][0]: 120
|
軸の概念
多次元配列「ndarray」は,通常のプログラミング言語の配列と考えることもできます.違いは,ndarray にはとても便利な機能が沢山あることです.その便利な機能を使うためには軸(axis)という概念を理解する必要があります.
例えば4次元配列 arr[i][j][k][l] を考えます.ここで,軸:axis=0 は最初の軸 [i] を,軸:axis=1 は [j] を,軸:axis=2 は [j] を,軸:axis=3 は [j] を表します.軸を表す整数は,配列の添字の序数を表しているでけです.
例えば,ndarray のメソッド ope() があるとします.そして,これは配列 arr に作用します.しばしば,配列に作用するメソッドは,arr.ope(axis=2) というような書き方許されます.これは配列にメソッド ope が作用した結果を返します.具体的には,res=arr.ope(axis=2) というような感じです.このように記述すると,メソッド ope() は,軸:axis=2 (三番目の[k]) を値を変えた値を引数(複数)に作用します.式で書くと以下のような感じです.
\begin{align}
res[i][j][l]=ope(arr[i][j][0][l],\,arr[i][j][1][l],\,arr[i][j][2][l],\,\cdots)
\end{align}
理解を深めるために,もうちょっと具体的な例を示します.以下のプログラムは,軸:axis=1 に沿って,配列の和
\begin{align}
a[i][k]=\sum_j a[i][j][k]
\end{align}
を計算します.プログラムでは,018 行の「res = a.sum(axis=1) 」です.以下のプログラムで確認できます.
ndarray の軸を示す例 |
実行結果 |
001 import numpy as np
002
003 a = np.array([[\
004 [ 0, 1, 2],\
005 [ 10, 11, 12],\
006 [ 20, 31, 32]],\
007 [\
008 [100, 101, 102],\
009 [110, 111, 112],\
010 [120, 121, 122]],\
011 [\
012 [200, 201, 202],\
013 [210, 211, 212],\
014 [220, 221, 222]]])
015
016
017 # --- res[i][j] = sum_k a[i][k][j] ---
018 res = a.sum(axis=1)
019 print(res, '\n')
020
021 print(a[0][0][0]+a[0][1][0]+a[0][2][0]) # res[0][0]
022 print(a[0][0][1]+a[0][1][1]+a[0][2][1]) # res[0][1]
023 print(a[0][0][2]+a[0][1][2]+a[0][2][2]) # res[0][2]
024 print(a[1][0][0]+a[1][1][0]+a[1][2][0]) # res[1][0]
025 print(a[1][0][1]+a[1][1][1]+a[1][2][1]) # res[1][1]
026 print(a[1][0][2]+a[1][1][2]+a[1][2][2]) # res[1][2]
027 print(a[2][0][0]+a[2][1][0]+a[2][2][0]) # res[2][0]
028 print(a[2][0][1]+a[2][1][1]+a[2][2][1]) # res[2][1]
029 print(a[2][0][2]+a[2][1][2]+a[2][2][2]) # res[2][2]
|
[[ 30 43 46]
[330 333 336]
[630 633 636]]
30
43
46
330
333
336
630
633
636
|
多次元配列の生成
配列作成ルーチン
NumPy には,いくつかの配列作成の関数が用意されています.詳細は,「Array creation routines」に記載されています.これらは配列作成に便利です.
値がゼロ or 1
Python Numpy の配列生成メソッド
メソッド |
動作 |
empty(shape[, dtype, order]) |
初期化無し(値不定)で,配列を生成します.[詳しい説明と具体例] |
empty_like(a[, dtype, order, subok]) |
既存の配列と同じシェイプ・型で,初期化なしで配列を生成します.[詳しい説明と具体例] |
eye(N[, M, k, dtype, order]) |
正方行列でない単位行列を生成します.対角成分以外も 1 にできます.[詳しい説明と具体例] |
identity(n[, dtype]) |
正方行列の単位行列を生成します.[詳しい説明と具体例] |
ones(shape[, dtype, order]) |
すべての要素の値が 1 の配列を生成します.[詳しい説明と具体例] |
ones_like(a[, dtype, order, subok]) |
既存の配列と同じシェイプ・型で,要素の値が 1 の配列を生成します.[詳しい説明と具体例] |
zeros(shape[, dtype, order]) |
すべての要素の値が 0 の配列を生成します.[詳しい説明と具体例] |
zeros_like(a[, dtype, order, subok]) |
既存の配列と同じシェイプ・型で,要素の値が 0 の配列を生成します.[詳しい説明と具体例] |
full(shape, fill_value[, dtype, order]) |
すべての要素の値が同一の配列を生成します.要素の値は任意に指定できます.[詳しい説明と具体例] |
full_like(a, fill_value[, dtype, order, subok]) |
既存の配列と同じシェイプ・型で,すべての要素の値が同一の配列を生成します.要素の値は任意に指定できます.[詳しい説明と具体例] |
既存のデータから
Python Numpy の配列を既存のデータから生成
メソッド |
動作 |
array(object[, dtype, copy, order, subok, ndmin]) |
配列のようなオブジェクト (リストやタプルなど) から配列を作成.[詳しい説明と具体例] |
asarray(a[, dtype, order]) |
配列へ変換します.元の配列が numpy.ndarray の場合は,同じ id になる.[詳しい説明と具体例] |
asanyarray(a[, dtype, order]) |
Convert the input to an ndarray, but pass ndarray subclasses through. |
ascontiguousarray(a[, dtype]) |
Return a contiguous array in memory (C order). |
asmatrix(data[, dtype]) |
Interpret the input as a matrix. |
copy(a[, order]) |
Return an array copy of the given object. |
frombuffer(buffer[, dtype, count, offset]) |
Interpret a buffer as a 1-dimensional array. |
fromfile(file[, dtype, count, sep]) |
Construct an array from data in a text or binary file. |
fromfunction(function, shape, **kwargs) |
Construct an array by executing a function over each coordinate. |
fromiter(iterable, dtype[, count]) |
Create a new 1-dimensional array from an iterable object. |
fromstring(string[, dtype, count, sep]) |
A new 1-D array initialized from text data in a string. |
loadtxt(fname[, dtype, comments, delimiter, …]) |
Load data from a text file. |
record arrays
Python Numpy の配列をから
メソッド |
動作 |
core.records.array(obj[, dtype, shape, …]) |
Construct a record array from a wide-variety of objects. |
core.records.fromarrays(arrayList[, dtype, …]) |
create a record array from a (flat) list of arrays |
core.records.fromrecords(recList[, dtype, …]) |
create a recarray from a list of records in text form |
core.records.fromstring(datastring[, dtype, …]) |
create a (read-only) record array from binary data contained in |
core.records.fromfile(fd[, dtype, shape, …]) |
Create an array from binary file data |
character arrays
Python Numpy の配列をから
メソッド |
動作 |
core.defchararray.array(obj[, itemsize, …]) |
Create a chararray. |
core.defchararray.asarray(obj[, itemsize, …]) |
Convert the input to a chararray, copying the data only if necessary. |
Numerical ranges
Python Numpy の配列をから
メソッド |
動作 |
arange([start,] stop[, step,][, dtype]) |
Return evenly spaced values within a given interval. |
linspace(start, stop[, num, endpoint, …]) |
Return evenly spaced numbers over a specified interval. |
logspace(start, stop[, num, endpoint, base, …]) |
Return numbers spaced evenly on a log scale. |
geomspace(start, stop[, num, endpoint, dtype]) |
Return numbers spaced evenly on a log scale (a geometric progression). |
meshgrid(*xi, **kwargs |
Return coordinate matrices from coordinate vectors. |
mgrid |
nd_grid instance which returns a dense multi-dimensional “meshgrid”. |
ogrid |
開いた多次元「meshgrid」を返す nd_grid インスタンス[詳しい説明と具体例]. |
Building matrices
Python Numpy の配列をから
メソッド |
動作 |
diag(v[, k]) |
Extract a diagonal or construct a diagonal array. |
diagflat(v[, k]) |
Create a two-dimensional array with the flattened input as a diagonal. |
tri(N[, M, k, dtype]) |
An array with ones at and below the given diagonal and zeros elsewhere. |
tril(m[, k]) |
Lower triangle of an array. |
triu(m[, k]) |
Upper triangle of an array. |
vander(x[, N, increasing]) |
Generate a Vandermonde matrix. |
The Matrix class
Python Numpy の配列をから
メソッド |
動作 |
mat(data[, dtype]) |
Interpret the input as a matrix. |
bmat(obj[, ldict, gdict]) |
Build a matrix object from a string, nested sequence, or array. |
リストを使う方法
リストを変換
numpy の多次元配列は,Python に備わっているリストを使って作成することができます.リストを np.array(リスト) とすると,多次元配列になります(具体例).
arr = np.array(リスト)
リスト内包表記を使う
リスト内包表記を使うと,かなり複雑なリストの作成が可能です.そのリストを配列に変換します.
一次元
一次元の配列の作成は,次のようにします(具体例).
arr = np.array([式 for 変数 in リスト])
多次元
多次元の配列の作成は,次のようにします(具体例).
arr = np.array([[[式 for 変数 in リスト] 変数 in リスト] 変数 in リスト])
空配列の生成と値の追加
空の配列を作ると便利なことがあります.特に最初に空の配列を作り,値を追加することがあります.空の配列は,空のリスト ([]) を作り,nd.array() で多次元配列 (ndarray) に変換します(具体例).
arr = np.array([])
arr = np.append(arr, 3.14)
値を指定
ゼロ埋め
要素がゼロで埋められた配列は,各軸の要素数が書かれたタプルを引数とした「np.zero(要素数のタプル)」を使います.
np.zero()でゼロ埋め配列 |
実行結果 |
import numpy as np
a = np.zeros((2, 4, 6))
print(a)
|
[[[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]]
[[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]]]
|
連続した値の設定
要素が連続した値をとる配列は,「numpy.arange(x0, x1, dx).reshape(n1, n2, n3, …) 」とします.x0 は初期値,x1 は端の値, dx は増分です.「numpy.arange(x0, x1, dx)」で連続した一次元の配列を生成します.x1 以下の値,x1は生成されません.そして,reshape()を使うことにより,多次元にできます(具体例).
arr_1D = np.arange(x0, x1, dx)
arr_2D = np.arange(x0, x1, dx).reshape(n1, n2, n3, …)
ファイルからの読み込み
genfromtxt() を使って,ファイルから配列 (二次元) の値を読み込むことができます.詳細は「ファイル: 読み込み の genfromtxt を使った読み込み」を参照下さい,
要素の抽出(スライシング)
配列の一部を取り出すことをスライシング,あるいはインデキシングと言います.
インデックスによる指定
固定で指定
インデックスを指定することにより,配列の要素を取り出すことができます.具体例を以下に示します.これらの動作は説明するまでも無いですね.配列名を書けば全てが選択されます.軸 (配列のインデックス) の選択もできます.
インデックスによる配列の要素抽出 |
実行結果 |
import numpy as np
ary = np.arange(0,1000,1).reshape(10,10,10)[0:3, 0:3, 0:3]
print("-- ary ---")
print(ary)
print("\n-- ary[2] --")
print(ary[2])
print("\n-- ary[2][1] --")
print(ary[2][1])
print("\n-- ary[2][1][0] --")
print(ary[2][1][0])
|
-- ary -----------
[[[ 0 1 2]
[ 10 11 12]
[ 20 21 22]]
[[100 101 102]
[110 111 112]
[120 121 122]]
[[200 201 202]
[210 211 212]
[220 221 222]]]
-- ary[2] --------
[[200 201 202]
[210 211 212]
[220 221 222]]
-- ary[2][1] -----
[210 211 212]
-- ary[2][1][0] --
210
|
範囲で指定
先の例では,任意の第二軸でスライスした配列を取得できません.そのような場合,より一般的な 配列[軸1指定, 軸2指定,軸3指定, …]を使います.軸指定には,番号指定(例 [2]),範囲指定(例 [3:7]),全て指定([:])があります.範囲指定を [3:7] とすると,インデックス[3, 4, 5, 6]の指定になります.以下,具体例を示します.
インデックス(範囲指定)による配列の要素抽出 |
実行結果 |
import numpy as np
ary = np.arange(0,1000,1).reshape(10,10,10)[0:4, 0:4, 0:4]
print("\n-- ary[1:3] --")
print(ary[1:3])
print("\n-- ary[:,1] --")
print(ary[:, 1])
print("\n-- ary[:,:,2] --")
print(ary[:,:,2])
print("\n-- ary[1:3, 0:2, 1:3] --")
print(ary[1:3, 0:2, 1:3]) |
-- ary[1:3] --
[[[100 101 102 103]
[110 111 112 113]
[120 121 122 123]
[130 131 132 133]]
[[200 201 202 203]
[210 211 212 213]
[220 221 222 223]
[230 231 232 233]]]
-- ary[:,1] --
[[ 10 11 12 13]
[110 111 112 113]
[210 211 212 213]
[310 311 312 313]]
-- ary[:,:,2] --
[[ 2 12 22 32]
[102 112 122 132]
[202 212 222 232]
[302 312 322 332]]
-- ary[1:3, 0:2, 1:3] --
[[[101 102]
[111 112]]
[[201 202]
[211 212]]]
|
配列の変形
インデックス(軸)の交換
transopse()
transpose() を使うと任意の軸を簡単に入れ替えられます.配列のインデックスは軸を表します.例えば三次元配列 ary[ix][iy][iz] は,3つの軸 (ix, iy, iz) を持ちます.メソッド transpose() では,それぞれの軸に整数 (0, 1, 2) が割り振られています.(ix=0, iy=1, iz=2) のようにです.もちろん,4, 5, …, 次元でも同じです.軸を入れ替えて ary[iy][iz][ix] とするには,ary.transpose(1, 2, 0)とします.より複雑な四次元配列を使った例を以下に示します.
numpy.transpose()の例 |
実行結果 |
import numpy as np
#----- 四次元配列 ---------
a = np.arange(0,10000,1).reshape(10, 10, 10, 10)
#----- b[k][i][l][j] = a[i][j][k][l] -----
b = a.transpose(2,0,3,1)
print('a = ', a[9][7][1][3])
print('b = ', b[1][9][3][7])
|
a = 9713
b = 9713
|
引数無しで transpose() を使うと,配列のインデックスの並びが逆順になります.それは,以下の例で確認できます.
numpy.transpose(引数なし)の例 |
実行結果 |
import numpy as np
#----- 5次元配列 ---------
a = np.arange(0,100000,1).reshape(10, 10, 10, 10, 10)
#----- b[m][l][k][j][i] = a[i][j][k][l][m] -----
b = a.transpose()
print('a = ', a[8][7][6][5][4])
print('b = ', b[4][5][6][7][8])
|
a = 87654
b = 87654
|
二次元に配列の場合,引数なしの transpose() は理にかなった名前です.結果は,転置行列になります.
swapaxes()
軸の入れ替えを行うメソッドには,transpose() の他に swapaxes() があります.この swapaxes() は指定した二つの軸の入れ替えを行います.transpose() のように,一度に複数の軸の入れ替えはできません.メソッド名のとおりですね.
numpy.swapaxes()の例 |
実行結果 |
import numpy as np
#----- 四次元配列 ---------
a = np.arange(0,10000,1).reshape(10, 10, 10, 10)
#----- b[i][k][j][l] = a[i][j][k][l] -----
b = a.swapaxes(1,2)
print('a = ', a[1][2][3][4])
print('b = ', b[1][3][2][4])
|
a = 1234
b = 1234
|
代入
配列の特定の要素の値の変更には,インデックスを指定します.例えば,「arr[3][6][2] = 3.14」のようにします.スカラーの場合は簡単です.配列の場合は,以下のようにします.[もっと詳しい具体例]
arr =np.array([[[1, 1, 1], [1, 1, 1], [1, 1, 1]],\
[[1, 1, 1], [1, 1, 1], [1, 1, 1]]])
arr[0, 1, 2] = -9
arr[1][1][0:2] = [-12, -23]
arr[0, 0, 0:2] = [-99, -98]
メソッド
numpy.ndarray のメソッド
メソッド |
動作 |
all([axis, out, keepdims]) |
全てのエレメントが真の時に真を返す[具体例] |
any([axis, out, keepdims]) |
エレメントのうち少なくともひとつが True の場合に,True を返す. |
argmax([axis, out]) |
最大要素のインデックスを返す. |
argmin([axis, out]) |
Return indices of the minimum values along the given axis of a. |
argpartition(kth[, axis, kind, order]) |
Returns the indices that would partition this array. |
argsort([axis, kind, order]) |
Returns the indices that would sort this array. |
astype(dtype[, order, casting, subok, copy]) |
Copy of the array, cast to a specified type. |
byteswap([inplace]) |
Swap the bytes of the array elements |
choose(choices[, out, mode]) |
Use an index array to construct a new array from a set of choices. |
clip([min, max, out]) |
Return an array whose values are limited to [min, max]. |
compress(condition[, axis, out]) |
Return selected slices of this array along given axis. |
conj() |
Complex-conjugate all elements. |
conjugate() |
Return the complex conjugate, element-wise. |
copy([order]) |
Return a copy of the array. |
cumprod([axis, dtype, out]) |
Return the cumulative product of the elements along the given axis. |
cumsum([axis, dtype, out]) |
Return the cumulative sum of the elements along the given axis. |
diagonal([offset, axis1, axis2]) |
Return specified diagonals. |
dot(b[, out]) |
Dot product of two arrays. |
dump(file) |
Dump a pickle of the array to the specified file. |
dumps() |
Returns the pickle of the array as a string. |
fill(value) |
Fill the array with a scalar value. |
flatten([order]) |
Return a copy of the array collapsed into one dimension. |
getfield(dtype[, offset]) |
Returns a field of the given array as a certain type. |
item(*args) |
Copy an element of an array to a standard Python scalar and return it. |
itemset(*args) |
Insert scalar into an array (scalar is cast to array’s dtype, if possible) |
max([axis, out, keepdims]) |
Return the maximum along a given axis. |
mean([axis, dtype, out, keepdims]) |
Returns the average of the array elements along given axis. |
min([axis, out, keepdims]) |
Return the minimum along a given axis. |
newbyteorder([new_order]) |
Return the array with the same data viewed with a different byte order. |
nonzero() |
Return the indices of the elements that are non-zero. |
partition(kth[, axis, kind, order]) |
Rearranges the elements in the array in such a way that value of the element in kth position is in the position it would be in a sorted array. |
prod([axis, dtype, out, keepdims]) |
Return the product of the array elements over the given axis |
ptp([axis, out]) |
Peak to peak (maximum - minimum) value along a given axis. |
put(indices, values[, mode]) |
Set a.flat[n] = values[n] for all n in indices. |
ravel([order]) |
Return a flattened array. |
repeat(repeats[, axis]) |
Repeat elements of an array. |
reshape(shape[, order]) |
Returns an array containing the same data with a new shape. |
resize(new_shape[, refcheck]) |
Change shape and size of array in-place. |
round([decimals, out]) |
Return a with each element rounded to the given number of decimals. |
searchsorted(v[, side, sorter]) |
Find indices where elements of v should be inserted in a to maintain order. |
setfield(val, dtype[, offset]) |
Put a value into a specified place in a field defined by a data-type. |
setflags([write, align, uic]) |
Set array flags WRITEABLE, ALIGNED, (WRITEBACKIFCOPY and UPDATEIFCOPY), respectively. |
sort([axis, kind, order]) |
Sort an array, in-place. |
squeeze([axis]) |
Remove single-dimensional entries from the shape of a. |
std([axis, dtype, out, ddof, keepdims]) |
Returns the standard deviation of the array elements along given axis. |
sum([axis, dtype, out, keepdims]) |
Return the sum of the array elements over the given axis. |
swapaxes(axis1, axis2) |
Return a view of the array with axis1 and axis2 interchanged. |
take(indices[, axis, out, mode]) |
Return an array formed from the elements of a at the given indices. |
tobytes([order]) |
Construct Python bytes containing the raw data bytes in the array. |
tofile(fid[, sep, format]) |
Write array to a file as text or binary (default). |
tolist() |
Return the array as a (possibly nested) list. |
tostring([order]) |
Construct Python bytes containing the raw data bytes in the array. |
trace([offset, axis1, axis2, dtype, out]) |
Return the sum along diagonals of the array. |
transpose(*axes) |
Returns a view of the array with axes transposed. |
var([axis, dtype, out, ddof, keepdims]) |
Returns the variance of the array elements, along given axis. |
view([dtype, type]) |
ビューを返します.コピーと異なり,データをメモリーにコピーしません.[具体例] |
テクニック
nearest_index = (np.abs(array - value)).argmin()
ページ作成情報
参考資料
- 本ページの作成には,以下の書籍を参考にしました.
中久喜 健司 技術評論社 売り上げランキング: 16,041
更新履歴
|