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

Как подсчитать значения в определенном диапазоне в массиве Numpy?

У меня есть массив значений NumPy. Я хочу подсчитать, сколько из этих значений находится в определенном диапазоне, скажем, x < 100 и x > 25. Я прочитал о счетчике, но, похоже, он действителен только для определенных значений, а не диапазонов значений. Я искал, но ничего не нашел относительно моей конкретной проблемы. Если бы кто-то мог указать мне на правильную документацию, я был бы признателен. Спасибо вам

Я пробовал это

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

Но он просто дает мне числа между 25 и 99.

ИЗМЕНИТЬ Данные, которые я использую, были созданы другой программой. Затем я использовал script для чтения данных и сохранил их как список. Затем я взял список и включил его в массив с использованием массива (r).

Edit

Результат работы

 >>> 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')
4b9b3361

Ответ 1

Если ваш массив называется a, количество элементов, выполняющих 25 < x < 100, равно

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

Выражение (25 < a) & (a < 100) приводит к булевскому массиву с той же формой, что и a со значением True для всех элементов, удовлетворяющих условию. Суммирование по этому булевому массиву рассматривает значения True как значения 1 и False как 0.

Ответ 2

Вы можете использовать histogram. Вот пример базового использования:

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

В вашем конкретном случае это выглядит примерно так:

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

Кроме того, если у вас есть список строк, вы должны явно указать тип, так что numpy знает, чтобы создать массив float вместо списка строк.

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

Ответ 3

Основываясь на хорошем подходе Sven, вы также можете сделать более прямые:

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

Вначале создается массив логических значений с одним логическим значением для каждого входного числа в массиве a, а затем подсчитывается количество значений, отличных от False (т.е. True) (что дает количество совпадающих чисел).

Обратите внимание, однако, что этот подход в два раза медленнее, чем подход Sven .sum(), на массив из 100k чисел (NumPy 1.6.1, Python 2.7.3) - около 300 мкс против 150 мкс.

Ответ 4

Ответ Sven - это способ сделать это, если вы не хотите продолжать обрабатывать соответствующие значения.
Следующие два примера возвращают копии только с соответствующими значениями:

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

Или:

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

Пример интерпретатора:

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

В приведенных выше примерах используется "бит-мудрый и" (&) для выполнения элементарного вычисления вдоль двух булевых массивов, которые вы создаете для целей сравнения.
Другой способ написать Sven отличный ответ, например:

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

Булевские массивы содержат True значения, когда условие соответствует, и False, когда это не так. Бонусный аспект логических значений заключается в том, что True эквивалентен 1 и False до 0.

Ответ 5

Я думаю, что ответ @Sven Marnach довольно приятный, потому что он работает в самом массиве numpy, который будет быстрым и эффективным (реализация C).

Мне нравится ставить тест в одно условие, например 25 < x < 100, поэтому я, вероятно, сделаю это примерно так:

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