Consider the following:
import numpy as np
arr = np.arange(3 * 4 * 5).reshape((3, 4, 5))
If I slice arr using slices, I get, e.g.:
arr[:, 0:2, :].shape
# (3, 2, 5)
If now I slice arr using a mixture of slice() and tuple(), I get:
arr[:, (0, 1), :].shape
# (3, 2, 5)
np.all(arr[:, (0, 1), :] == arr[:, :2, :])
# True
and:
arr[:, :, (0, 1)].shape
# (3, 4, 2)
np.all(arr[:, :, (0, 1)] == arr[:, :, :2])
# True
HOWEVER, if I do:
arr[:, (0, 1), (0, 1)].shape
# (3, 2)
which is basically, arr[:, 0, 0] and arr[:, 1, 1] concatenated.
I was expecting to get:
arr[:, (0, 1), (0, 1)].shape
# (3, 2, 2)
np.all(arr[:, (0, 1), (0, 1)] == arr[:, :2, :2])
# True
but it is clearly not the case.
If I concatenate two separate slicing, I would be able to obtain the desired result, i.e.:
arr[:, (0, 1), :][:, :, (0, 1)].shape
# (3, 2, 2)
np.all(arr[:, (0, 1), :][:, :, (0, 1)] == arr[:, :2, :2])
# True
Is it possible to obtain the same result as arr[:, (0, 1), :][:, :, (0, 1)] but USING a single slicing?
Now, this example is not so interesting, because I could replace the tuple() with a slice(), but if that is not true, it all becomes a lot more relevant, e.g.:
arr[:, (0, 2, 3), :][:, :, (0, 2, 3, 4)]
# [[[ 0  2  3  4]
#   [10 12 13 14]
#   [15 17 18 19]]
#  [[20 22 23 24]
#   [30 32 33 34]
#   [35 37 38 39]]
#  [[40 42 43 44]
#   [50 52 53 54]
#   [55 57 58 59]]]
for which arr[:, (0, 2, 3), (0, 2, 3, 4)] would be a much more convenient syntax.
EDIT
@Divakar @hpaulj and @MadPhysicist comments / answers pointed towards a properly broadcasted Iterable to be equivalent of multiple concatenated slicing.
However, this is not the case, e.g.:
s = np.ix_((0, 1), (0, 1, 2, 3))
arr[s[0], slice(3), s[1]]
# [[[ 0  5 10]
#   [ 1  6 11]
#   [ 2  7 12]
#   [ 3  8 13]]
# 
#  [[20 25 30]
#   [21 26 31]
#   [22 27 32]
#   [23 28 33]]]
But:
arr[(0, 1), :, :][:, :3, :][:, :, (0, 1, 2, 3)]
# [[[ 0  1  2  3]
#   [ 5  6  7  8]
#   [10 11 12 13]]
# 
#  [[20 21 22 23]
#   [25 26 27 28]
#   [30 31 32 33]]]
and:
np.all(arr[:2, :3, :4] == arr[(0, 1), :, :][:, :3, :][:, :, (0, 1, 2, 3)])
# True
np.all(arr[s[0], slice(3), s[1]] == arr[(0, 1), :, :][:, :3, :][:, :, (0, 1, 2, 3)])
# False