评估数组中的k个相邻(加或减)元素

时间:2016-12-10 08:57:19

标签: python python-3.x numpy

我一直在努力完成对一维numpy数组中k个相邻元素施加不等式阈值的任务 - 我应该添加到左侧和右侧。例如:

if x[i+-100] < .05:

这是我能说清楚的最好,显然它不起作用。但我希望我的观点更清楚。换句话说,我想辨别元素x的正负100个元素中的任何元素是否具有大于.05的值。这是我对上下文的全部功能:(这里我也有-.05)

def vector_recode(x):
    if (x[i+-100]) > .05 or (x[i+-100]) < -.05:
        return X
    else:
        return 0
recode_function = np.vectorize(vector_recode)

- 为清楚起见,上面的函数试图获取足够接近零的值并将它们刷新为零,或者如果附近的任何[+ -100]元素的值高于.05 in绝对术语,保持x原样。

我有一种沉闷的感觉,我可能不得不求助于循环,但是np总是让我惊讶于它的效率,而且我希望有人有洞察力可以帮助像我这样的其他人处理{{ 1}}相邻元素。

我对此过程的另一项研究涉及k和卷积矩阵。但是,我不认为这种方法很容易适用于我的情况 - 这只是一维左右相邻元素。我以前错了。非常感谢任何帮助。

如果有帮助,我会尝试做一个成功的例子:

scipy.ndimage

这里假设代替正负100,正负5.在数组&#39; A&#39;没有大于.05或小于-.05的值,因此在矢量化函数中x及其相邻元素将被设置为零。而阵列&#39; B&#39;有一个大于.05的元素。它是0.23,因此这意味着函数将留下x以及x的正或负5个相邻元素。正如有人正确指出的那样,可能需要仔细处理边界元素。你可以想象&#39; A&#39;和&#39; B&#39;作为1个较大数组的两个不同的数组或分区。我不确定分区是否可行,但我对任何事情都持开放态度。希望这更容易理解。

3 个答案:

答案 0 :(得分:1)

尝试制作像这样的if子句

if (any(x[i:i+100:1]) > .05) and any((x[i-100:i+1:1]) < -.05):

但是,您还必须在vector_recode的定义中指定向量x中的索引i

此外this帖子似乎也有更简洁的方式。

答案 1 :(得分:1)

一个技巧是将数组分别剪切到-0.050.05处的最小 - 最大限制,并检查哪些元素已更改,表明这些元素超出了最小 - 最大限制。这将导致二进制数组。然后,我们使用二进制扩张将此 ANY 查找扩展到某个窗口大小。最后,基于扩展掩码,我们使用np.where在保留原始元素或设置为0之间进行选择。

因此,实现将是 -

from scipy.ndimage.morphology import binary_dilation

def reset_arr(x, W, T): # x: input array, W : window size, T : threshold as +-
    mask = binary_dilation(x.clip(min=-T, max=T) != x,np.ones(2*W+1))
    return np.where(mask, x, 0)

示例运行 -

In [376]: x
Out[376]: 
array([ 0.06821936,  0.66300942,  0.15449635,  1.52260898,  0.41346868,
       -0.48343499,  0.45386276,  2.1888203 ,  0.36947105, -0.17660172])

In [377]: reset_arr(x, W = 1, T = 0.5)
Out[377]: 
array([ 0.06821936,  0.66300942,  0.15449635,  1.52260898,  0.41346868,
        0.        ,  0.45386276,  2.1888203 ,  0.36947105,  0.        ])

答案 2 :(得分:1)

请注意,Python的abs()函数也接受NumPy数组,并返回组件结果:

>>> import numpy as np
>>> abs(np.array([-5, 1, -3.3, -2, 0, 11]))
array([  5. ,   1. ,   3.3,   2. ,   0. ,  11. ])

>运算符也是如此,即使另一个操作数是标量:

>>> abs(np.array([0.01, 0.07, -0.07, -0.02, 5])) > 0.05
array([False,  True,  True, False,  True], dtype=bool)

我们可以将其插入到Divakar's answer

的方法中
from scipy.ndimage.morphology import binary_dilation

def recode_function(data, k, threshold):
    mask = binary_dilation( abs(data) > threshold, np.ones(2 * k + 1) )
    return np.where(mask, data, 0)

如果你不关心零值的符号,那么(组件方式)乘法掩码和数据也是有效的:

from scipy.ndimage.morphology import binary_dilation

def recode_function(data, k, threshold):
    mask = binary_dilation( abs(data) > threshold, np.ones(2 * k + 1) )
    return mask * data