Подсчитайте все значения в матрице, превышающей значение
Я должен подсчитать все значения в матрице (2-d массив), которые больше 200.
Код, который я записал для этого:
za=0
p31 = numpy.asarray(o31)
for i in range(o31.size[0]):
for j in range(o32.size[1]):
if p31[i,j]<200:
za=za+1
print za
o31
это образ, и я преобразую его в матрицу, а затем нахожу значения.
4 ответа:
Функция
numpy.where
- Ваш друг. Поскольку он реализован, чтобы в полной мере использовать тип данных массива, для больших изображений вы должны заметить улучшение скорости по сравнению с чистым решением python, которое вы предоставляете.Использование numpy.где непосредственно будет выдана логическая маска, указывающая, соответствуют ли определенные значения вашим условиям:
>>> data array([[1, 8], [3, 4]]) >>> numpy.where( data > 3 ) (array([0, 1]), array([1, 1]))
И маску можно использовать для индексации массива напрямую, чтобы получить фактические значения:
>>> data[ numpy.where( data > 3 ) ] array([8, 4])
Именно от того, где вы его возьмете, будет зависеть в какой форме вы хотели бы получить результаты.
Это очень просто с булевыми массивами:
p31 = numpy.asarray(o31) za = (p31 < 200).sum() # p31<200 is a boolean array, so `sum` counts the number of True elements
Есть много способов достичь этого, например, сглаживать и фильтровать или просто перечислять, но я думаю, что использованиеboolean/mask array является самым простым (и iirc намного быстрее):
>>> y = np.array([[123,24123,32432], [234,24,23]]) array([[ 123, 24123, 32432], [ 234, 24, 23]]) >>> b = y > 200 >>> b array([[False, True, True], [ True, False, False]], dtype=bool) >>> y[b] array([24123, 32432, 234]) >>> len(y[b]) 3 >>>> y[b].sum() 56789
Обновление :
Как ответил ннеоннео, если все, что вам нужно, - это число элементов, которое проходит порог, вы можете просто сделать:
>>>> (y>200).sum() 3
Что является более простым решением.
Сравнение скорости с
filter
:### use boolean/mask array ### b = y > 200 %timeit y[b] 100000 loops, best of 3: 3.31 us per loop %timeit y[y>200] 100000 loops, best of 3: 7.57 us per loop ### use filter ### x = y.ravel() %timeit filter(lambda x:x>200, x) 100000 loops, best of 3: 9.33 us per loop %timeit np.array(filter(lambda x:x>200, x)) 10000 loops, best of 3: 21.7 us per loop %timeit filter(lambda x:x>200, y.ravel()) 100000 loops, best of 3: 11.2 us per loop %timeit np.array(filter(lambda x:x>200, y.ravel())) 10000 loops, best of 3: 22.9 us per loop *** use numpy.where *** nb = np.where(y>200) %timeit y[nb] 100000 loops, best of 3: 2.42 us per loop %timeit y[np.where(y>200)] 100000 loops, best of 3: 10.3 us per loop