Comment compter les valeurs dans une certaine plage dans un tableau Numpy?

J'ai un tableau NumPy de valeurs. Je veux compter combien de ces valeurs sont dans une plage spécifique disons x 25. J'ai lu à propos du compteur, mais il semble n'être valide que pour les valeurs specif pas les plages de valeurs. J'ai cherché, mais n'ai rien trouvé concernant mon problème. Si quelqu'un pouvait me diriger vers la documentation appropriée, Je l'apprécierais. Merci

J'ai essayé ceci

   X = array(X)
   for X in range(25, 100):
       print(X)

Mais ça me donne juste les chiffres entre 25 et 99.

Modifier Les données que j'utilise ont été créées par un autre programme. J'ai ensuite utilisé un script pour lire les données et de les stocker sous forme de liste. J'ai ensuite pris la liste et l'ai transformée en un tableau en utilisant array (r).

Modifier

Le résultat de l'exécution

 >>> 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')
32
demandé sur Alexander 2012-03-05 04:22:05

5 réponses

Si votre tableau est appelé a, le nombre d'éléments de l'accomplissement de 25 < x < 100 est

((25 < a) & (a < 100)).sum()

L'expression {[3] } aboutit à un tableau booléen de la même forme que a avec la valeur True pour tous les éléments qui satisfont la condition. La somme de ce tableau booléen traite les valeurs True comme 1 et les valeurs False comme 0.

58
répondu Sven Marnach 2012-03-05 00:34:57

Vous pouvez utiliser histogram. Voici un exemple d'utilisation de base:

>>> 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. ]))

Dans votre cas particulier, cela ressemblerait à ceci:

>>> numpy.histogram(a, bins=(25, 100))
(array([73]), array([ 25, 100]))

De plus, lorsque vous avez une liste de chaînes, vous devez spécifier explicitement le type, de sorte que numpy sache produire un tableau de flotteurs au lieu d'une liste de chaînes.

>>> 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.])
8
répondu senderle 2012-03-05 02:56:25

En S'appuyant sur la bonne approche de Sven, vous pouvez également faire le plus direct:

numpy.count_nonzero((25 < a) & (a < 100))

Cela crée d'abord un tableau de booléens avec un booléen pour chaque numéro d'entrée dans array a, Puis compte le nombre de valeurs non-False (c'est-à-dire True) (ce qui donne le nombre de nombres correspondants).

Notez cependant que cette approche est deux fois plus lente que L'approche .sum() de Sven, sur un tableau de 100k nombres (NumPy 1.6.1, Python 2.7.3) - environ 300 µs contre 150 µs.

7
répondu Eric Lebigot 2012-05-07 08:20:45

La réponse de Sven est la façon de le faire si vous ne souhaitez pas continuer à traiter les valeurs correspondantes.
Les deux exemples suivants renvoient des copies avec uniquement les valeurs correspondantes:

np.compress((25 < a) & (a < 100), a).size

Ou:

a[(25 < a) & (a < 100)].size

Exemple de session d'interpréteur:

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

Les exemples ci-dessus utilisent un "bit-wise and" (&) pour faire un calcul par élément le long des deux tableaux booléens que vous créez à des fins de comparaison.
Une autre façon d'écrire L'excellente réponse de Sven, par exemple, est:

np.bitwise_and(25 < a, a < 100).sum() 

Les tableaux booléens contiennent des valeurs True lorsque la condition correspond, et False quand ce n'est pas le cas.
Un aspect bonus des valeurs booléennes est que True est équivalent à 1 et False à 0.

4
répondu bernie 2012-03-05 01:34:45

Je pense que la réponse de @Sven Marnach est assez agréable, car elle fonctionne sur le tableau numpy lui-même qui sera rapide et efficace (implémentation C).

J'aime mettre le test dans une condition comme 25 < x < 100, donc je le ferais probablement quelque chose comme ceci:

len([x for x in a.ravel() if 25 < x < 100])

2
répondu wim 2012-03-05 01:26:36