Булева маскировка массива двумерных массивов - PullRequest
0 голосов
/ 26 августа 2018

Я не понимаю ни одного примера в этом тупом уроке .

a = np.arange(12).reshape(3,4)
b1 = np.array([False, True, True])
b2 = np.array([True, False, True, False])

Тогда почему a[b1,b2] вернет array([4, 10])? Разве это не должно вернуть array([[4, 6], [8, 10]])?

Любое подробное объяснение приветствуется!

Ответы [ 3 ]

0 голосов
/ 26 августа 2018

Когда вы индексируете массив с несколькими массивами, он индексирует пары элементов из индексирующих массивов

>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b1
array([False,  True,  True], dtype=bool)
>>> b2
array([ True, False,  True, False], dtype=bool)
>>> a[b1, b2]
array([ 4, 10])

Обратите внимание, что это эквивалентно:

>>> a[(1, 2), (0, 2)]
array([ 4, 10])

, которые являютсяэлементы в a[1, 0] и a[2, 2]

>>> a[1, 0]
4
>>> a[2, 2]
10

Из-за этого попарного поведения вы не можете вообще индексировать с отдельными массивами длины (они должны иметь возможность широковещательной передачи).Так что этот пример является своего рода несчастным случаем, так как оба индексных массива имеют два индекса, где они True;например, если у одного было три значения True, вы получите сообщение об ошибке:

>>> b3 = np.array([True, True, True, False])
>>> a[b1, b3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,)

Так что это, в частности, дает вам понять, что индексные массивы должны быть в состоянии транслироваться вместе (так, чтобы он могразумно отсеивать индексы (например, если один индексный массив имеет только одно значение, которое будет повторяться с каждым значением из другого индексного массива).

Чтобы получить ожидаемые результаты, можно проиндексироватьрезультат отдельно:

>>> a[b1][:, b2]
array([[ 4,  6],
       [ 8, 10]])

В противном случае вы также можете превратить ваш индексный массив в двумерный массив с той же формой, что и a, но обратите внимание, что если вы это сделаете, результатом будет линейный массив (поскольку любое количество элементов может быть извлечено, что, конечно, не может быть квадратным):

>>> a[np.outer(b1, b2)]
array([ 4,  6,  8, 10])
0 голосов
/ 20 июня 2019

Другой способ применить общую булеву 2D маску к двумерному массиву numpy заключается в следующем:

Использовать матричное поэлементное умножение:

import numpy as np

n = 100
mask = np.identity(n)
data = np.random.rand(n,n)

data_masked = data * mask

В этом случайном примере вы держите только элементы по диагонали. Маска может быть любой n на n матрицей.

0 голосов
/ 26 августа 2018

Индексы true для первого массива:

>>> i = np.where(b1)
>>> i 
array([1,2])

Для второго массива они

>>> j = np.where(b2)
>>> j
array([0,1])

При совместном использовании этих индексных масок

>>> a[i,j]
array([4, 10])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...