python - transpuesta - ¿Cómo contar valores en un cierto rango en una matriz Numpy?
tamaño de un arreglo numpy (5)
Tengo una matriz de valores NumPy. Quiero contar cuántos de estos valores están en un rango específico, por ejemplo, x <100 y x> 25. He leído sobre el contador, pero parece ser válido solo para valores específicos, no para rangos de valores. He buscado, pero no he encontrado nada con respecto a mi problema específico. Si alguien pudiera indicarme la documentación adecuada, lo agradecería. Gracias
Lo he intentado
X = array(X)
for X in range(25, 100):
print(X)
Pero solo me da los números entre 25 y 99.
EDITAR Los datos que estoy usando fue creado por otro programa. Luego usé un script para leer los datos y almacenarlos como una lista. Luego tomé la lista y la entregué a una matriz usando la matriz (r).
Editar
El resultado de correr
>>> a[0:10]
array([''29.63827346'', ''40.61488812'', ''25.48300065'', ''26.22910525'',
''42.41172923'', ''20.15013315'', ''34.95323355'', ''13.03604098'',
''29.71097606'', ''9.53222141''],
dtype=''<U11'')
Creo que la respuesta de @Sven Marnach es bastante agradable, ya que opera en la propia matriz numpy que será rápida y eficiente (implementación de C).
Me gusta poner la prueba en una condición como 25 < x < 100
, así que probablemente lo haga de la siguiente manera:
len([x for x in a.ravel() if 25 < x < 100])
La respuesta de Sven es la forma de hacerlo si no desea seguir procesando los valores coincidentes.
Los dos ejemplos siguientes devuelven copias con solo los valores coincidentes:
np.compress((25 < a) & (a < 100), a).size
O:
a[(25 < a) & (a < 100)].size
Ejemplo de sesión de intérprete:
>>> import numpy as np
>>> a = np.random.randint(200,size=100)
>>> a
array([194, 131, 10, 100, 199, 123, 36, 14, 52, 195, 114, 181, 138,
144, 70, 185, 127, 52, 41, 126, 159, 39, 68, 118, 124, 119,
45, 161, 66, 29, 179, 194, 145, 163, 190, 150, 186, 25, 61,
187, 0, 69, 87, 20, 192, 18, 147, 53, 40, 113, 193, 178,
104, 170, 133, 69, 61, 48, 84, 121, 13, 49, 11, 29, 136,
141, 64, 22, 111, 162, 107, 33, 130, 11, 22, 167, 157, 99,
59, 12, 70, 154, 44, 45, 110, 180, 116, 56, 136, 54, 139,
26, 77, 128, 55, 143, 133, 137, 3, 83])
>>> np.compress((25 < a) & (a < 100),a).size
34
>>> a[(25 < a) & (a < 100)].size
34
Los ejemplos anteriores utilizan un "bit-wise" y "(bit)" para hacer un cálculo de elemento a lo largo de las dos matrices booleanas que se crean para propósitos de comparación.
Otra forma de escribir la excelente respuesta de Sven, por ejemplo, es:
np.bitwise_and(25 < a, a < 100).sum()
Las matrices booleanas contienen valores True
cuando la condición coincide y False
cuando no lo hace.
Un aspecto adicional de los valores booleanos es que True
es equivalente a 1 y False
a 0.
Partiendo del buen enfoque de Sven, también puedes hacerlo de manera más directa:
numpy.count_nonzero((25 < a) & (a < 100))
Esto primero crea una matriz de booleanos con un booleano para cada número de entrada en la matriz a
, y luego cuenta el número de valores no falsos (es decir, verdaderos) (que da la cantidad de números que coinciden).
Sin embargo, tenga en cuenta que este enfoque es dos veces más lento que el .sum()
Sven de .sum()
en una matriz de 100k números (NumPy 1.6.1, Python 2.7.3), alrededor de 300 μs versus 150 μs.
Podría usar histogram
. Aquí hay un ejemplo de uso básico:
>>> import numpy
>>> a = numpy.random.random(size=100) * 100
>>> numpy.histogram(a, bins=(0.0, 7.3, 22.4, 55.5, 77, 79, 98, 100))
(array([ 8, 14, 34, 31, 0, 12, 1]),
array([ 0. , 7.3, 22.4, 55.5, 77. , 79. , 98. , 100. ]))
En su caso particular, se vería algo como esto:
>>> numpy.histogram(a, bins=(25, 100))
(array([73]), array([ 25, 100]))
Además, cuando tiene una lista de cadenas, debe especificar explícitamente el tipo, de modo que numpy
sepa producir una matriz de flotantes en lugar de una lista de cadenas.
>>> strings = [str(i) for i in range(10)]
>>> numpy.array(strings)
array([''0'', ''1'', ''2'', ''3'', ''4'', ''5'', ''6'', ''7'', ''8'', ''9''],
dtype=''|S1'')
>>> numpy.array(strings, dtype=float)
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
Si su matriz se llama a
, la cantidad de elementos que cumplen 25 < x < 100
es
((25 < a) & (a < 100)).sum()
La expresión (25 < a) & (a < 100)
da como resultado una matriz booleana con la misma forma que a
con el valor True
para todos los elementos que satisfacen la condición. Al sumarse a esta matriz booleana, se tratan los valores True
como 1
y los valores False
como 0
.