2016-12-25 2 views
3

Примера:Mask конкретных значений из массива

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

array([[1, 2, 0, 3, 4], 
     [0, 4, 2, 1, 3], 
     [4, 3, 2, 0, 1], 
     [4, 2, 3, 0, 1], 
     [1, 0, 2, 3, 4], 
     [4, 3, 2, 0, 1]], dtype=int64) 

У меня есть набор (с переменной длиной, порядок не имеет значения) «плохих» значения:

{2, 3} 

Я хочу, чтобы вернуть маску, скрывающую эти значения:

array([[False, True, False, True, False], 
     [False, False, True, False, True], 
     [False, True, True, False, False], 
     [False, True, True, False, False], 
     [False, False, True, True, False], 
     [False, True, True, False, False]], dtype=bool) 

Каков самый простой способ сделать это в NumPy?

ответ

4

Использование np.in1d что дает нам сплюснутый маску таких согласующих вхождений, а затем изменить обратно к входной форме массива для требуемого выхода, например, так -

np.in1d(a,[2,3]).reshape(a.shape) 

Пример запуска -

In [5]: a 
Out[5]: 
array([[1, 2, 0, 3, 4], 
     [0, 4, 2, 1, 3], 
     [4, 3, 2, 0, 1], 
     [4, 2, 3, 0, 1], 
     [1, 0, 2, 3, 4], 
     [4, 3, 2, 0, 1]]) 

In [6]: np.in1d(a,[2,3]).reshape(a.shape) 
Out[6]: 
array([[False, True, False, True, False], 
     [False, False, True, False, True], 
     [False, True, True, False, False], 
     [False, True, True, False, False], 
     [False, False, True, True, False], 
     [False, True, True, False, False]], dtype=bool) 
1

Могут быть более простые пути, чем это. Но это может быть один из способов:

import numpy as np 

a = np.array([[1, 2, 0, 3, 4], 
     [0, 4, 2, 1, 3], 
     [4, 3, 2, 0, 1], 
     [4, 2, 3, 0, 1], 
     [1, 0, 2, 3, 4], 
     [4, 3, 2, 0, 1]], dtype=np.int64) 

f = np.vectorize(lambda x: x in {2,3}) 
print f(a) 

Выход:

[[False True False True False] 
[False False True False True] 
[False True True False False] 
[False True True False False] 
[False False True True False] 
[False True True False False]] 
+1

'vectorize' это просто' for' цикл, хотя, не так ли? – endolith

3
In [965]: np.any([x==i for i in (2,3)],axis=0) 
Out[965]: 
array([[False, True, False, True, False], 
     [False, False, True, False, True], 
     [False, True, True, False, False], 
     [False, True, True, False, False], 
     [False, False, True, True, False], 
     [False, True, True, False, False]], dtype=bool) 

Это итерация, но если набор (2,3) мал (относительно размера x), это относительно быстро. На самом деле для малых arr2, np.in1d делает это:

 mask = np.zeros(len(ar1), dtype=np.bool) 
     for a in ar2: 
      mask |= (ar1 == a) 

Создание замаскированный массива из этого:

In [970]: np.ma.MaskedArray(x,mask) 
Out[970]: 
masked_array(data = 
[[1 -- 0 -- 4] 
[0 4 -- 1 --] 
[4 -- -- 0 1] 
[4 -- -- 0 1] 
[1 0 -- -- 4] 
[4 -- -- 0 1]], 
      mask = 
[[False True False True False] 
[False False True False True] 
[False True True False False] 
[False True True False False] 
[False False True True False] 
[False True True False False]], 
     fill_value = 999999) 
+1

То, что '[x == i для i в (2,3)]' будет занимать «N» раз больше памяти, чем конечный вывод, N - количество элемен- тов в массиве поиска. Askers post sample, который не обязательно связан с этими точными небольшими входами, особенно когда они ищут производительность. – Divakar

+0

эквивалент цикла in1d' сохраняет больше памяти. Скорее всего, то же самое. Но мы должны были бы протестировать. Это не может быть оптимальным решением для всех случаев, но я думаю, что это хорошее базовое решение. – hpaulj

+0

Да, накладные расходы на функцию с np.in1d, но в основном сопоставимые характеристики, я бы подумал. – Divakar

Смежные вопросы