У меня есть 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,

И

  1. элементы в 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 ...

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

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

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

1
steve 5 Июл 2019 в 20:22

3 ответа

Лучший ответ

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

Итак, в вашем новом примере вы также должны получить обратную маску. Вместо 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.

4
Georgy 9 Июл 2019 в 12:26

Вы можете создать маску, используя изображение 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
Nils Werner 8 Июл 2019 в 20:34

В соответствии с условиями желаемое значение после размещения двух условий: [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 списка.

Это то, что тебе надо?

0
Joe 5 Июл 2019 в 17:53