Python: маскирование многомерных массивов

2

Что такое эквивалентная реализация pythonic для следующего простого фрагмента кода в Matlab.

Matlab:


B = 2D array of integers as indices [1...100]
A = 2D array of numbers: [10x10]
A[B] = 0

который хорошо работает, например, для B[i]=42, он находит положение 2 столбца 5. В Python он вызывает ошибку: вне привязки, которая логическая. Однако для перевода вышеуказанного кода Matlab в Python мы ищем питонические способы. Также рассмотрите проблему для более высоких размеров, например:


B = 2D array of integers as indices [1...3000]
C = 3D array of numbers: [10x10x30]
C[B] = 0

Один из способов, о котором мы думали, состоит в том, чтобы преобразовать элементы массива индексов как i,j вместо абсолютной позиции. То есть, позиция 42 - divmod(42,m=10)[::-1] >>> (2,4). Таким образом, мы будем иметь векторы индексов nx2 >>> ii,jj, которые легко могут быть использованы для индексации A. Мы думали, что это может быть лучший способ, эффективный и для более высоких измерений в Python.

  • 0
    «В Python это вызывает ошибку: вне границы, что логично» ... что вызывает это? Можете ли вы показать, что вы пробовали в Python?
  • 0
    Почему вы используете 2D-массив в качестве индекса другого 2D-массива?
Показать ещё 2 комментария
Теги:
multidimensional-array
masking

1 ответ

5
Лучший ответ

Вы можете использовать .ravel() в массиве (A) перед его индексированием, а затем .reshape() после.

В качестве альтернативы, поскольку вы знаете A.shape, перед индексированием вы можете использовать np.unravel_index для другого массива (B).

Пример 1:

>>> import numpy as np
>>> A = np.ones((5,5), dtype=int)
>>> B = [1, 3, 7, 23]
>>> A
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]])
>>> A_ = A.ravel()
>>> A_[B] = 0
>>> A_.reshape(A.shape)
array([[1, 0, 1, 0, 1],
       [1, 1, 0, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 0, 1]])

Пример 2:

>>> b_row, b_col = np.vstack([np.unravel_index(b, A.shape) for b in B]).T
>>> A[b_row, b_col] = 0
>>> A
array([[1, 0, 1, 0, 1],
       [1, 1, 0, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 0, 1]])

Обнаружено позже: вы можете использовать numpy.put

>>> import numpy as np
>>> A = np.ones((5,5), dtype=int)
>>> B = [1, 3, 7, 23]
>>> A.put(B, [0]*len(B))
>>> A
array([[1, 0, 1, 0, 1],
       [1, 1, 0, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 0, 1]])
  • 2
    Спасибо за примеры. Я собирался попросить вас продемонстрировать свое решение на примере ... вау! Вы сделали, прежде чем я отправлю это. С этими примерами идея теперь ясна. Оба метода полезны.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню