根据多个条件获取NumPy数组的连续元素组

时间:2019-07-05 17:22:08

标签: python arrays numpy

我有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 previous question,每次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.]

现在,我想将自己的病情更改为连续两次或更多次的多重病情:

    a中的
  1. 元素小于c

AND

    b中的
  1. 元素小于d

使用以下代码:

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

我知道我的条件(连续2次或更多次)在索引151617上仅满足1次。

现在,我想提取与满足我的条件的那些索引相对应的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 ...

所需的输出数组应为索引151617之一,与数组[3 4 4]中的值a对应。

有人可以指出我可以用来提取满足多种条件的数组的python工具吗?

注意:这是我的问题的一个最小示例,在我的“现实生活”中,我需要连续找到满足我的条件14次或以上的数组!

3 个答案:

答案 0 :(得分:4)

请注意,在您的previous question中,当您在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]

a的第15-17个元素。

答案 1 :(得分:0)

根据条件,放置两个条件后的期望输出是:[3,4,4]的{​​{1}}或a的{​​{1}}对吗?

尝试:

[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 :(得分:0)

您可以使用类似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])