Маскирование многомерного массива NumPy

Я хочу замаскировать многомерный массив, скажем, 4D-массив A формы N x N x N x N, где у меня есть другая маска (a, b и c) для последних трех измерений. Итак, a, b и c - это векторы со значениями True и False, имеющими длину N. Попытка замаскировать A как A[:,a,b,c] дает исключение (что это пытается сделать?), A[:,:,:,d][:,:,c][:,b] работает, но создает ненужные промежуточные звенья. Если бы у меня были маски для каждого измерения, я бы использовал их как A[numpy.ix_(a, b, c, d)] для создания промежуточного массива индексации, но я не хочу создавать фиктивную маску a, которая везде является True. Спасибо.

Редактировать:

import numpy as np

A = np.arange(3**4).reshape((3,3,3,3))
a = np.asarray([True, True, True])
b = np.asarray([False, False, True])
c = np.asarray([True, True, False])

B = A[:,:,:,c][:,:,b][:,a]
print(B)

B2 = A[:,a,b,c]
print(B2)

выход:

[[[[ 6  7]]

  [[15 16]]

  [[24 25]]]


 [[[33 34]]

  [[42 43]]

  [[51 52]]]


 [[[60 61]]

  [[69 70]]

  [[78 79]]]]
Traceback (most recent call last):
  File "test2.py", line 11, in <module>
    B2 = A[:,a,b,c]
IndexError: shape mismatch: indexing arrays could not be broadcast 
together with shapes (3,) (1,) (2,)

Не работает A[numpy.ix_(a, b, c, d)]?

Divakar 09.10.2018 14:38

Ой! Вы правы, numpy.ix_ в этом случае работает! Я попытался сделать вопрос более общим, но слишком сильно изменил суть проблемы. В моем случае я действительно хочу замаскировать только 2-е, 3-е и 4-е измерения. Так что что-то вроде A[:,numpy.ix_(b,c,d)] вместо A[:,:,:,d][:,:,c][:,b]. Первое, однако, приводит к Traceback (most recent call last): File "test2.py", line 10, in <module> print(A[:,np.ix_(b,c,d)]) ValueError: could not broadcast input array from shape (2,1) into shape (1).

Max 09.10.2018 14:50

Пожалуйста, отредактируйте вопрос аналогичным образом.

Divakar 09.10.2018 14:53

Для этого конкретного случая: np.moveaxis(np.moveaxis(A,0,-1)[np.ix_(b,c,d)],-1,0). В общем случае вы можете захотеть работать с slice.

Divakar 09.10.2018 15:02

Я отредактировал вопрос и спасибо за вашу помощь. Не могли бы вы привести мне пример того, как я бы использовал slice в этом случае?

Max 09.10.2018 15:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
136
1

Ответы 1

Вы можете добиться этого с помощью трюка транспонирования:

In [19]: (A.T[np.ix_(c.T, b.T, a.T)]).T
Out[19]:
array([[[[ 6,  7]],

    [[15, 16]],

    [[24, 25]]],


   [[[33, 34]],

    [[42, 43]],

    [[51, 52]]],


   [[[60, 61]],

    [[69, 70]],

    [[78, 79]]]])

Другие вопросы по теме