Рассмотрим следующее:
import numpy as np
arr = np.arange(3 * 4 * 5).reshape((3, 4, 5))
Если я нарежу arr
, используя slice
, я получу, например:
arr[:, 0:2, :].shape
# (3, 2, 5)
Если теперь я нарежу arr
, используя смесь slice()
и tuple()
, я получу:
arr[:, (0, 1), :].shape
# (3, 2, 5)
np.all(arr[:, (0, 1), :] == arr[:, :2, :])
# True
а также:
arr[:, :, (0, 1)].shape
# (3, 4, 2)
np.all(arr[:, :, (0, 1)] == arr[:, :, :2])
# True
ОДНАКО, если я сделаю:
arr[:, (0, 1), (0, 1)].shape
# (3, 2)
что в основном arr[:, 0, 0]
и arr[:, 1, 1]
объединено.
Я ожидал получить:
arr[:, (0, 1), (0, 1)].shape
# (3, 2, 2)
np.all(arr[:, (0, 1), (0, 1)] == arr[:, :2, :2])
# True
но это явно не так.
Если я объединим два отдельных среза, я смогу получить желаемый результат, то есть:
arr[:, (0, 1), :][:, :, (0, 1)].shape
# (3, 2, 2)
np.all(arr[:, (0, 1), :][:, :, (0, 1)] == arr[:, :2, :2])
# True
Можно ли получить тот же результат, что и arr[:, (0, 1), :][:, :, (0, 1)]
, но ИСПОЛЬЗУЯ один срез?
Теперь этот пример не так интересен, потому что я мог бы заменить tuple()
на slice()
, но если это не так, все становится намного более актуальным, например:
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]]]
для которого arr[:, (0, 2, 3), (0, 2, 3, 4)]
был бы гораздо более удобным синтаксисом.
РЕДАКТИРОВАТЬ
Комментарии/ответы @Divakar @hpaulj и @MadPhysicist указывали на то, что правильно транслируемый Iterable эквивалентен множественным конкатенированным срезам.
Однако это не так, например:
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]]]
Но:
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]]]
а также:
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
np.ix_
-x,y = np.ix_([0,2,3],[0,2,3,4]); arr[:,x,y]
. Илиarr[:,np.array([0,2,3])[:,None],[0,2,3,4]]
. - person Divakar   schedule 27.05.2019sub2ind
для преобразования индексов в плоское индексирование. По сути, то, что просто в MATLAB, (просто) немного сложнее вnumpy
, и наоборот для другого. - person hpaulj   schedule 27.05.2019slice()
, не зная априори, каков размер объекта, который нужно разрезать, так что функция, например.ixb()
для прозрачного использования, какarr[ixb(a, b, c)]
вместоarr[a, :, :][:, b, :][:, :, c]
, независимо от того, что такоеa
,b
иc
, не может быть создано таким образом. - person norok2   schedule 28.05.2019