python - tablas - Cuente todos los valores en una matriz mayor que un valor
como usar pandas en python (4)
Tengo que contar todos los valores en una matriz (matriz de 2 d) que son mayores que 200.
El código que escribí para esto es:
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
es una imagen y la estoy convirtiendo en una matriz y luego encuentro los valores.
Mi pregunta es, ¿hay una manera más simple de hacer esto?
Aquí hay una variante que usa indexación sofisticada y tiene los valores reales como intermedios:
p31 = numpy.asarray(o31)
values = p31[p31<200]
za = len(values)
Esto es muy sencillo con matrices booleanas:
p31 = numpy.asarray(o31)
za = (p31 < 200).sum() # p31<200 is a boolean array, so `sum` counts the number of True elements
Hay muchas maneras de lograr esto, como aplanar y filtrar o simplemente enumerar, pero creo que usar Boolean / mask array es el más fácil (y iirc es mucho más rápido):
>>> 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
Actualización :
Como ha respondido nneonneo, si todo lo que quiere es la cantidad de elementos que pasan el umbral, simplemente puede hacer:
>>>> (y>200).sum()
3
que es una solución más simple.
Comparación de velocidad con 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
La función numpy.where
es tu amiga. Debido a que está implementado para aprovechar al máximo el tipo de datos de la matriz, para las imágenes de gran tamaño, debe observar una mejora de velocidad con respecto a la solución de python pura que proporciona.
El uso de numpy.where directamente arrojará una máscara booleana que indica si ciertos valores coinciden con sus condiciones:
>>> data
array([[1, 8],
[3, 4]])
>>> numpy.where( data > 3 )
(array([0, 1]), array([1, 1]))
Y la máscara se puede usar para indexar la matriz directamente para obtener los valores reales:
>>> data[ numpy.where( data > 3 ) ]
array([8, 4])
El lugar exacto desde donde lo tomará dependerá de la forma en que desee los resultados.