Отфильтровать массив NumPy, но сохранить исходное значение - PullRequest
1 голос
/ 26 сентября 2019

Другими словами, поддерживает ли numpy «просеивание»?

У меня есть два массива:

a = np.array([1, 0, 2, 3, 0, 4])
b = np.array([1, 0, 0, 0, 0, 6])

Я хочу вернуть новый массив c, содержащийисходные значения a, основанные на маске b:

c = a[b > 0] 
>> c
np.array([1, 4])
# but what I want is:
# np.array([1, 0, 0, 0, 0, 4])

Я могу обойти это, сделав понимание списка:

c = [a[i] if b[i] > 0 else 0 for i in range(len(a))]

Я также мог бы сделатьмаска, но для этого потребуется двукратная итерация:

mask = [1 if b[i] > 0 else 0 for i in range(len(b))]  
c = ma.array(a, mask=mask)

Есть ли что-то нативное для numpy, которое позволяет одному массиву действовать как сито для другого массива?

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

Использование np.where :

result = np.where(b > 0, a, 0)
print(result)

Или просто умножить:

import numpy as np

a = np.array([1, 0, 2, 3, 0, 4])
b = np.array([1, 0, 0, 0, 0, 6])

print(a * (b > 0))

Выход

[1 0 0 0 0 4]
1 голос
/ 26 сентября 2019

Другая идея состоит в том, чтобы инициализировать массив результатов c нулями (на основе формы a), а затем использовать логическую маску для заполнения значений из a.Ниже приведена иллюстрация:

# result array
In [28]: c = np.zeros_like(a)  

# get the indices where nonzero values exist in array `b`
In [29]: nonzero_idx = np.nonzero(b)  

# extract the corresponding values from the array `a` and
# fill in the array `c` using the same indices
In [30]: c[nonzero_idx] = a[nonzero_idx] 

In [31]: c 
Out[31]: array([1, 0, 0, 0, 0, 4])

Объяснение случая использования numpy.where:

In [42]: np.where(b >  0, *[a, 0])   
Out[42]: array([1, 0, 0, 0, 0, 4])

часть b > 0 являетсяусловие, которое мы собираемся проверить, с записями в массиве a.Если это условие выполнено, то эти элементы будут возвращены, иначе мы вернемся 0;вот почему мы передаем 0 в качестве третьего аргумента numpy.where()

Если вы хотите, чтобы вместо 0 s были заполнены некоторые другие значения, то передайте требуемое значение.Например, допустим, мы хотим, чтобы -9 заполнялось в местах, где условие (b > 0) не выполняется (то есть False), тогда мы будем писать что-то вроде:

In [43]: np.where(b >  0, *[a, -9])     
Out[43]: array([ 1, -9, -9, -9, -9,  4])
...