web-dev-qa-db-fra.com

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

J'ai un tableau de valeurs NumPy. Je veux compter combien de ces valeurs sont dans une plage spécifique, disons x <100 et x> 25. J'ai lu sur le compteur, mais il ne semble être valable que pour des valeurs spécifiques et non pour des plages de valeurs. J'ai cherché, mais je n'ai rien trouvé concernant mon problème spécifique. Si quelqu'un pouvait me diriger vers la documentation appropriée, je l'apprécierais. Merci

J'ai essayé ça

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

Mais cela me donne juste des 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 les stocker sous forme de liste. J'ai ensuite pris la liste et je l'ai transformée en tableau à l'aide de 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')
39
Stripers247

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

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

L'expression (25 < a) & (a < 100) donne 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 sommation sur ce tableau booléen traite les valeurs de True comme 1 et False valeurs comme 0.

71
Sven Marnach

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, afin que numpy sache produire un tableau de flottants 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.])
9
senderle

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

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 le tableau a, puis compte le nombre de valeurs non fausses (c'est-à-dire vraies) (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.

8
Eric O Lebigot

La réponse de Sven est la façon de le faire si vous ne souhaitez pas traiter davantage 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 interprète:

>>> 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 par bit et" (&) pour effectuer 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 dans le cas contraire.
Un aspect bonus des valeurs booléennes est que True est équivalent à 1 et False à 0.

4
bernie

Je pense que la réponse de @Sven Marnach est plutôt sympa, 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
wim