NumPy配列ndarrayの次元をEllipsis(...)で省略して指定
NumPy配列ndarrayのインデックス[]で範囲を指定するときにPythonの組み込み定数Ellipsis(3点ドット...)を使うと途中の次元を省略して指定できる。
ndarrayをprint()などで出力するときに要素の表示を省略するかしないかを設定する方法については以下の記事を参照。
Pythonの組み込み定数Ellipsis(3点ドット ...)
Pythonでは組み込み定数としてEllipsisが定義されている。
print(Ellipsis)
# Ellipsis
source: ellipsis_object.py
ドット(ピリオド)3つを連続した...(3点ドット)でも記述可能。
print(...)
# Ellipsis
source: ellipsis_object.py
Ellipsisと...は同じellipsisオブジェクト。
print(type(Ellipsis))
# <class 'ellipsis'>
print(type(...))
# <class 'ellipsis'>
print(Ellipsis is ...)
# True
source: ellipsis_object.py
Python3.12時点では基本文法としてEllipsis(...)の用途は特にないが、以下に示すように、NumPyではEllipsis(...)の便利な使い方が用意されている。
NumPy配列ndarrayの次元を省略して指定
NumPyではEllipsis(...)を使うと配列ndarrayのインデックス[]で範囲を指定するときに途中の次元を省略できる。
以下の四次元配列を例とする。
import numpy as np
print(np.__version__)
# 1.26.1
a = np.arange(120).reshape(2, 3, 4, 5)
print(a.shape)
# (2, 3, 4, 5)
source: numpy_ellipsis.py
例えば、最後の次元だけを指定したい場合は:を使って以下のように書ける。
print(a[:, :, :, 0])
# [[[ 0 5 10 15]
# [ 20 25 30 35]
# [ 40 45 50 55]]
#
# [[ 60 65 70 75]
# [ 80 85 90 95]
# [100 105 110 115]]]
source: numpy_ellipsis.py
...を使うと以下のように書ける。
print(a[..., 0])
# [[[ 0 5 10 15]
# [ 20 25 30 35]
# [ 40 45 50 55]]
#
# [[ 60 65 70 75]
# [ 80 85 90 95]
# [100 105 110 115]]]
source: numpy_ellipsis.py
先頭と末尾の次元だけを指定したい場合も同様。途中の次元を...で省略できる。
print(a[0, :, :, 0])
# [[ 0 5 10 15]
# [20 25 30 35]
# [40 45 50 55]]
print(a[0, ..., 0])
# [[ 0 5 10 15]
# [20 25 30 35]
# [40 45 50 55]]
source: numpy_ellipsis.py
...ではなくEllipsisを使ってもよい。
print(a[Ellipsis, 0])
# [[[ 0 5 10 15]
# [ 20 25 30 35]
# [ 40 45 50 55]]
#
# [[ 60 65 70 75]
# [ 80 85 90 95]
# [100 105 110 115]]]
print(a[0, Ellipsis, 0])
# [[ 0 5 10 15]
# [20 25 30 35]
# [40 45 50 55]]
source: numpy_ellipsis.py
例は四次元なので:でも...でも大差ないが、さらに多次元だと...のほうが楽。:の場合は:の数を次元数に合わせないといけないが、...だと気にしなくてもよい。
当然ながら、...が2つ以上あるとどこを省略するか明確でないのでエラーになる。
# print(a[..., 0, ...])
# IndexError: an index can only have a single ellipsis ('...')
source: numpy_ellipsis.py
なお、:が最後の次元まで繰り返される場合は:を省略可能。...を書く必要もない(書いてもエラーにはならない)。
print(a[0, 0, :, :])
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]
# [15 16 17 18 19]]
print(a[0, 0])
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]
# [15 16 17 18 19]]
print(a[0, 0, ...])
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]
# [15 16 17 18 19]]
source: numpy_ellipsis.py