Как подсчитать значения в определенном диапазоне в массиве 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')
Ответы
Ответ 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])