Подтвердить что ты не робот

Подсчитайте все значения в матрице, превышающей значение

Мне нужно подсчитать все значения в матрице (2-й массив), которые больше 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 - это изображение, и я преобразовываю его в матрицу, а затем нахожу значения.

Мой вопрос: есть ли более простой способ сделать это?

4b9b3361

Ответ 1

Функция numpy.where - ваш друг. Поскольку он реализован для полного использования типа данных массива, для больших изображений вы должны заметить улучшение скорости по сравнению с чистым решением python, которое вы предоставляете.

Использование numpy.where напрямую даст булевскую маску, указывающую, соответствуют ли определенные значения вашим условиям:

>>> data
array([[1, 8],
       [3, 4]])
>>> numpy.where( data > 3 )
(array([0, 1]), array([1, 1]))

И маска может использоваться для индексации массива напрямую, чтобы получить фактические значения:

>>> data[ numpy.where( data > 3 ) ]
array([8, 4])

Точно, где вы берете его оттуда, будет зависеть от того, в какой форме вы хотите получить результаты.

Ответ 2

Это очень просто с булевыми массивами:

p31 = numpy.asarray(o31)
za = (p31 < 200).sum() # p31<200 is a boolean array, so `sum` counts the number of True elements

Ответ 3

Есть много способов добиться этого, например, сгладить и фильтровать или просто перечислить, но я думаю, что использование 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

Обновление

Как ответил nneonneo, если все, что вам нужно, это количество элементов, которые проходят порог, вы можете просто сделать:

>>>> (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

Ответ 4

Здесь вариант, который использует причудливую индексацию и имеет фактические значения в качестве промежуточного:

p31 = numpy.asarray(o31)
values = p31[p31<200]
za = len(values)

Ответ 5

Чтобы подсчитать количество значений больше чем x в любом массиве numpy, вы можете использовать:

n = len(matrix[matrix > x])

Логическое индексирование возвращает массив, содержащий только те элементы, для которых выполняется условие (matrix> x). Тогда len() считает эти значения.