NumPy: Ellipsis (...) for ndarray
In NumPy, you can use the Python built-in constant Ellipsis
(represented as three dots, ...
) within []
to omit specifying intermediate dimensions of an array (ndarray
).
For information on how to set whether to omit elements when outputting ndarray
with print()
, refer to the following article.
Python built-in constant Ellipsis
(three dots, ...
)
In Python, Ellipsis
is defined as a built-in constant.
print(Ellipsis)
# Ellipsis
Ellipsis
can also be represented as ...
, consisting of three dots.
print(...)
# Ellipsis
Ellipsis
and ...
are the same ellipsis
object.
print(type(Ellipsis))
# <class 'ellipsis'>
print(type(...))
# <class 'ellipsis'>
print(Ellipsis is ...)
# True
As of Python 3.12, Ellipsis
(...
) has no specific role in the basic syntax, but NumPy offers a practical application, as demonstrated below.
Ellipsis
(...
) in NumPy
In NumPy, Ellipsis
(...
) allows you to omit intermediate dimensions when specifying a range of an array (ndarray
) with []
.
Consider the following four-dimensional array as an example.
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)
For example, to specify only the last dimension, you can write it using :
like below.
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]]]
Using ...
, it can be written as follows.
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]]]
The same applies when specifying only the first and last dimensions. Intermediate dimensions can be omitted with ...
.
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]]
You can also use Ellipsis
instead of ...
.
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]]
In a four-dimensional example, the difference between using :
and ...
is minimal. However, ...
becomes more convenient for higher-dimensional arrays. While :
requires matching the number of dimensions, ...
does not have this requirement.
Using two or more ...
creates ambiguity about where to omit and results in an error.
# print(a[..., 0, ...])
# IndexError: an index can only have a single ellipsis ('...')
If :
is used for each dimension leading up to the last one, it can be entirely omitted. In such cases, there is no necessity to use ...
, though including it does not result in an error.
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]]