NumPy 配列属性
この章では、NumPy 配列のいくつかの基本属性について学んでいきます。
NumPy 配列の次元数はランク(rank)と呼ばれ、ランクとは軸の数のこと、つまり配列の次元です。
1次元配列のランクは 1、2次元配列のランクは 2、以下同様です。
NumPy では、配列の各次元は軸(axis)、すなわち次元(dimensions)と呼ばれます。
例えば、2次元配列は「1次元配列から構成される1次元配列」と見なせます。外側の配列の各要素自体がまた1次元配列です。
ここで、第0軸は最も外側の配列の方向に相当し、第1軸は内側の配列の方向で、以下同様です。
軸の数、すなわちランクが、配列の次元数です。
多くの NumPy 関数は axis 引数をサポートしています。
2次元配列の場合、axis=0 は第0軸に沿って操作することを意味し、つまり各列に対して操作します。axis=1 は第1軸に沿って操作することを意味し、つまり各行に対して操作します。
以下では、shape が (2, 3) の2次元配列を例に、2つの軸の方向と各属性の意味を直感的に示します。
axis は「どの方向に圧縮するか」を表しており、「何行目/何列目」ではありません。axis=0 に沿った合計は複数の行を1行に圧縮するため、結果は各列の合計になります。
例
a = np.array([[1, 2, 3], [4, 5, 6]])
# 第0軸に沿って合計:行方向に圧縮し、各列の合計を求める
print(a.sum(axis=0))
# 第1軸に沿って合計:列方向に圧縮し、各行の合計を求める
print(a.sum(axis=1))
出力結果は次のとおりです:
[5 7 9] [ 6 15]
以下のインタラクティブなデモで、2つの軸の合計方向をより直感的に確認できます。ボタンをクリックして切り替えてください:
a.sum(axis=0) → [5 7 9]、第0軸に沿って各列の要素を1つの数に圧縮するNumPy 配列の中で比較的重要な ndarray オブジェクトの属性は次のとおりです:
| 属性 | 説明 |
|---|---|
ndarray.ndim | 配列のランク(rank)。すなわち配列の次元数または軸の数です。 |
ndarray.shape | 配列の次元。配列の各軸上のサイズを表します。2次元配列(行列)の場合、行数と列数を表します。 |
ndarray.size | 配列内の要素の総数。次に等しい:ndarray.shapeshape の各軸上のサイズの積。 |
ndarray.dtype | 配列内の要素のデータ型。 |
ndarray.itemsize | 配列内の各要素のサイズ(バイト単位)。 |
ndarray.flags | メモリレイアウトに関する情報を含みます。C または Fortran の連続したストレージであるか、読み取り専用であるかなどです。 |
ndarray.real | 配列内の各要素の実部(要素の型が複素数の場合)。 |
ndarray.imag | 配列内の各要素の虚部(要素の型が複素数の場合)。 |
ndarray.data | 配列要素を実際に格納するバッファ。通常はインデックスで要素にアクセスし、この属性を直接使用することはありません。 |
ndarray.ndim
ndarray.ndim は、配列の次元数(つまり配列の軸数)、すなわちランクを取得するために使用します。
例
a = np.arange(24)
print(a.ndim) # a は現在1次元のみ
# reshape でサイズを調整し、2ページ・4行・3列にする
b = a.reshape(2, 4, 3) # b は現在3次元
print(b.ndim)
出力結果は次のとおりです:
1 3
ndarray.shape
ndarray.shape は配列の次元を表し、タプルを返します。このタプルの長さが次元の数、すなわち ndim 属性(ランク)です。
例えば、2次元配列の shape はその「行数」と「列数」を表します。
shape タプルの順序は軸の順序と一致します。第0要素は第0軸のサイズ(行数)、第1要素は第1軸のサイズ(列数)です。
例
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.shape)
出力結果は次のとおりです:
(2, 3)
ndarray.shape は配列のサイズ調整にも使用できます。
例
a = np.array([[1, 2, 3], [4, 5, 6]])
a.shape = (3, 2)
print(a)
出力結果は次のとおりです:
[[1 2] [3 4] [5 6]]
NumPy には、配列のサイズを調整するための reshape 関数も用意されています。
例
a = np.array([[1, 2, 3], [4, 5, 6]])
b = a.reshape(3, 2)
print(b)
出力結果は次のとおりです:
[[1 2] [3 4] [5 6]]
2つの方法の違い:a.shape に直接代入すると配列 a 自体がその場で変更されます。一方、a.reshape(3, 2) は新しい配列オブジェクトを返し(通常は a とデータを共有します)、a 自体は変更されません。
ndarray.size
ndarray.size は、配列内の要素の総数を返します。これは shape の各軸上のサイズの積に等しいです。
例
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.shape) # shape は (2, 3)
print(a.size) # 要素の総数:2 × 3 = 6
出力結果は次のとおりです:
(2, 3) 6
ndarray.dtype
ndarray.dtype は、配列内の要素のデータ型を返します。
dtype オブジェクトには、型名や要素のビット幅などの情報が含まれます。例えば、int64 は64ビット整数、float32 は32ビット浮動小数点数を表します。
例
# 整数リストからはデフォルトで int64 配列が作成されます(Windows ではデフォルトで int32)
a = np.array([1, 2, 3])
print(a.dtype)
# 作成時に dtype 引数でデータ型を明示的に指定できます
b = np.array([1, 2, 3], dtype=np.float32)
print(b.dtype)
出力結果は次のとおりです:
int64 float32
ndarray.real と ndarray.imag
ndarray.real と ndarray.imag は、それぞれ配列内の各要素の実部と虚部を返します。主に要素の型が複素数(complex)の場合に使用します。
例
# 複素数配列を作成、デフォルトの型は complex128
a = np.array([1+2j, 3+4j, 5+6j])
print(a.real) # 各要素の実部
print(a.imag) # 各要素の虚部
出力結果は次のとおりです:
[1. 3. 5.] [2. 4. 6.]
ndarray.itemsize
ndarray.itemsize は、配列内の各要素のサイズをバイト単位で返します。
例えば、要素の型が float64 の配列の場合、itemsize 属性の値は 8 です(float64 は64ビットを占有し、8ビットが1バイトなので、64 ÷ 8 = 8バイト)。
また、要素の型が int32 の配列の場合、itemsize 属性の値は 4 です(32 ÷ 8)。
size と itemsize の積が、配列データが占める合計バイト数、すなわち ndarray.nbytes 属性の値です。
例
# 配列の dtype は int8、各要素は1バイト
x = np.array([1, 2, 3, 4, 5], dtype=np.int8)
print(x.itemsize)
# 配列の dtype は float64、各要素は8バイト
y = np.array([1, 2, 3, 4, 5], dtype=np.float64)
print(y.itemsize)
出力結果は次のとおりです:
1 8
ndarray.flags
ndarray.flags は ndarray オブジェクトのメモリ情報を返し、次の属性を含みます:
| 属性 | 説明 |
|---|---|
| C_CONTIGUOUS (C) | データが単一の C 言語スタイルの連続したメモリ領域にある |
| F_CONTIGUOUS (F) | データが単一の Fortran 言語スタイルの連続したメモリ領域にある |
| OWNDATA (O) | 配列が使用するメモリを所有しており、他のオブジェクトから借用していない |
| WRITEABLE (W) | データ領域に書き込み可能。この値を False に設定すると、データは読み取り専用になる |
| ALIGNED (A) | データとすべての要素がハードウェアに対して適切にアラインされている |
| WRITEBACKIFCOPY (X) | この配列は他の配列のコピーであり、この配列が解放されると、その内容は元の配列に書き戻される |
旧バージョンの UPDATEIFCOPY (U) は WRITEBACKIFCOPY の旧名称で、NumPy 1.14 で非推奨となり、NumPy 2.0 以降では完全に削除されたため、現在は使用すべきではありません。
C_CONTIGUOUS と F_CONTIGUOUS は、同一のデータがメモリ内でどのように並んでいるかを表します。同じ2次元配列には2つの典型的な格納方法があります:
例
x = np.array([1, 2, 3, 4, 5])
print(x.flags)
出力結果は:
C_CONTIGUOUS : True F_CONTIGUOUS : True OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : Falseその他の拡張