Как подсчитать группы определенного значения в массиве numpy 1d?

#python #arrays #numpy

#python #массивы #numpy

Вопрос:

У меня есть массивы numpy 1d с логическими значениями, которые выглядят так

 array_in = np.array([False, True, True, True, False, False, True, True, False])
 

Эти массивы имеют разную длину. Как вы можете видеть, есть части, где истинные значения расположены рядом друг с другом, поэтому у нас есть группы истинных и группы ложных значений. Я хочу подсчитать количество истинных групп. Для нашего случая мы имеем

 N = 2
 

Я попытался выполнить несколько циклов с условиями, но это стало действительно запутанным и запутанным.

Ответ №1:

Вы можете использовать np.diff для определения изменений между группами. Присоединяя False к началу и концу этого вычисления разницы, мы удостоверяемся, что True группы в начале и конце правильно подсчитаны.

 import numpy as np

array_in = np.array([False, True, True, True, False, False, True, True, False, True, False, True])

true_groups = np.sum(np.diff(array_in, prepend=False, append=False))//2

#print(true_groups)
>>>4
 

Комментарии:

1. Ваш результат равен 4, а не 2

2. Потому что этот входной массив отличается.

Ответ №2:

Если вы не хотите писать циклы и условия, вы можете срезать путь, рассмотрев это как проблему связанных компонентов.

 import numpy as np
from skimage import measure

array_in = np.array([False, True, True, True, False, False, True, True, False])
N = max(measure.label(array_in))
 

Когда массив передается в меру.функция label() обрабатывает значения 0 в этом массиве как «фоновые». Затем он просматривает все ненулевые значения, находит связанные области и нумерует их.

Например, вывод метки в приведенном выше массиве будет [0, 1, 1, 1, 0, 0, 2, 2, 0] . Естественно, затем выполнение простого max на выходе дает вам наибольшее число групп (здесь это 2), что также совпадает с количеством True групп.

Комментарии:

1. Интересный взгляд на проблему. Как это работает?

2. Когда массив передается в measure.label() функцию, он обрабатывает значения 0 в этом массиве как «фоновые». Затем он просматривает все ненулевые значения, находит связанные области и нумерует их. Например, вывод метки в приведенном выше массиве будет [0, 1, 1, 1, 0, 0, 2, 2, 0]. Естественно, затем выполнение простого max на выходе дает вам наибольшее число групп (здесь это 2), что также совпадает с числом истинных групп.

3. Хотите добавить это в свой ответ?

Ответ №3:

Простой способ найти количество групп True — это подсчитать количество False True последовательностей в массиве. При понимании списка это будет выглядеть так:

 sum([1 for i in range(1, len(x)) if x[i] and not x[i-1]])
 

В качестве альтернативы вы можете преобразовать исходный массив в строку из '0' s и '1' s и подсчитать количество '01' вхождений:

 ''.join([str(int(k)) for k in x]).count('01')
 

Ответ №4:

В native numpy можно создать векторизованное решение, проверив, сколько раз F изменяется T последовательно.

Например,

 np.bitwise_and(array_in[1:], ~array_in[:-1]).sum()   array_in[0]
 

Я вычисляю побитовое и каждого элемента массива с его предыдущим элементом после отрицания предыдущего элемента. Однако при этом первый элемент игнорируется, поэтому я добавляю его вручную.