Получить группы последовательных элементов массива NumPy на основе нескольких условий - PullRequest
1 голос
/ 05 июля 2019

У меня есть 2 массива NumPy следующим образом:

import numpy as np
a = np.array([1, 4, 2, 6, 4, 4, 6, 2, 7, 6, 2, 8, 9, 3, 6, 3, 4, 4, 5, 8])
b = np.array([2, 8, 3, 9, 9, 9, 7, 5, 4, 8, 6, 5, 4, 4, 7, 2, 1, 1, 9, 9])

и 2 постоянных числа:

c = 6
d = 3

На основе предыдущего вопроса , я могу извлечьмассив, каждый раз элементы в a меньше чем c, 2 или более раз подряд:

array = np.append(a, -np.inf)  # padding so we don't lose last element
mask = array >= c  # values to be removed
split_indices = np.where(mask)[0]
for subarray in np.split(array, split_indices + 1):
    if len(subarray) > 2:
        print(subarray[:-1])

, которые выводят:

[1. 4. 2.]
[4. 4.]
[3. 4. 4. 5.]

Теперь я хотел бы изменитьмое условие для множественного условия, где 2 или более раз подряд:

  1. элементов в a меньше c,

И

элементов в b меньше d

Используя следующий код:

mask = ((a< c) & (b< d))

Я знаю, что мои условия (2 раза или более последовательно)просто встречайте 1 раз по индексам 15, 16 и 17.

Теперь я хотел бы извлечь значение a, соответствующее тем индексам, где мои условия выполняются.

Основываясь на ответе по ссылке, я попытался:

a1= np.append(a, -np.inf)
a2=np.append(b, -np.inf)  # padding so we don't lose last element
mask = ((a1< c) & (a2< d))  # values to be removed
split_indices = np.where(mask)[0]
for subarray in np.split(a, split_indices + 1):
    if len(subarray) > 2:
        print(subarray[:-1])

Что удивительно, вернуть массив, где мои условия не соответствуют ...

[4 2 6 4 4 6 2 7 6 2 8 9 3 6]

Я также попробовал np.extract следующим образом:

np.extract((len(list(g))>=2 for i, g in ((a < c) & (b < d)) if i), a)

, которые возвращают мне значение 1, а не значение массива a ...

Требуемый выходной массив должен быть одним изindice 15, 16, 17, соответствующее значению [3 4 4] в массиве a.

Может ли кто-нибудь указать мне инструменты Python, которые я мог бы использовать для извлечения массива, выполняющего моинесколько условий?

ПРИМЕЧАНИЕ: это минимальный пример моей проблемы, в моей "реальной жизни" мне нужно найти массивs, которые соответствуют моим условиям 14 или более раз подряд!

Ответы [ 3 ]

4 голосов
/ 09 июля 2019

Обратите внимание, что в вашем предыдущем вопросе , когда вы искали элементы в array, которые меньше threshold, ваш mask был определен не как mask = array < threshold, а как обратное к это: mask = array >= threshold. Это потому, что он использовался позже, чтобы получить элементы, которые будут удалены .

Итак, в вашем новом примере вы также должны получить обратную маску. Вместо mask = (a1 < c) & (a2 < d) вам нужно mask = ~((a1 < c) & (a2 < d)):

a1= np.append(a, -np.inf)
a2 = np.append(b, -np.inf)
mask = ~((a1 < c) & (a2 < d))
split_indices = np.where(mask)[0]
for subarray in np.split(a, split_indices + 1):
    if len(subarray) > 2:
        print(subarray[:-1])

дает:

[3 4 4]

что составляет 15-17-е элементы a.

0 голосов
/ 08 июля 2019

Вы можете создать маску, используя изображение SciKit, например

import numpy as np
import skimage

N = 2
mask = ((a < c) & (b < d))
mask2 = np.zeros_like(mask)

tmp = skimage.util.view_as_windows(mask, N).all(axis=1)
mask2[N - 1:-N + 1] = skimage.util.view_as_windows(tmp, N).any(axis=1)
mask2
# array([False, False, False, False, False, False, False, False, False,
#        False, False, False, False, False, False,  True,  True,  True,
#        False, False])

и получите индексы и значения, используя

np.where(mask2)[0]  # array([15, 16, 17])
a[mask2]  # array([3, 4, 4])
0 голосов
/ 05 июля 2019

В соответствии с условиями, желаемый результат после размещения 2 условий: [3,4,4] от a или [2,1,1] от b верно?

Попробуйте:

a = [1, 4, 2, 6, 4, 4, 6, 2, 7, 6, 2, 8, 9, 3, 6, 3, 4, 4, 5, 8]
b = [2, 8, 3, 9, 9, 9, 7, 5, 4, 8, 6, 5, 4, 4, 7, 2, 1, 1, 9, 9]
c = 6
d = 3
condition_met = []
a_extract = []
b_extract = []

for i in range(0, len(a)):
    if a[i] < c and b[i] < d:
        condition_met.append(True)
    else:
        condition_met.append(False)

печать condition_met список дает [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, False, False]

Используя это, мы теперь проверяем ваши условия:

for i in range(0, len(condition_met)):
    if i == 0 and condition_met[i] == True and condition_met[i+1] == True:
        a_extract.append(a[i])
        b_extract.append(b[i])
    elif condition_met[i] == True and condition_met[i+1] == True and i != len(condition_met) - 1 and i > 0 or condition_met[i] == True and condition_met[i-1] == True and i != len(condition_met) - 1 and i > 0:
        a_extract.append(a[i])
        b_extract.append(b[i])
    elif condition_met[i] == True and condition_met[i-1] == True and i == len(condition_met) - 1:
        a_extract.append(a[i])
        b_extract.append(b[i])

Вы получите [3,4,4] для вашего a_extract списка и [2,1,1] для вашего b_extract списка.

Это то, что вам нужно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...