仅屏蔽numpy中的一定范围的索引

时间:2018-09-23 14:27:38

标签: python arrays numpy masking masked-array

我有一个ndarray。我需要屏蔽小于50的任何数字,直到遇到的第一个数字大于50。这应该在行的开头和结尾处进行。正确,当遇到的第一个数字> 50时,应停止屏蔽。

一行看起来像:

    [ 0   1   1   0  57  121  120  157  77  14   0   3   0   0   0   0  67 100  
    98  97 101 129 139 105  97 105 181 126  10   0   0]

我想要类似的东西

    [-- -- -- -- 57 121 120 157 77 14  0  3  0  0  0  0 67 100 98 97
 101 129 139 105 97 97 105 181 126 -- -- --]

遮罩应在第二行的57点之前停止,并在最后第四行的126点停止。

我尝试了ma.masked_where,但是它也屏蔽了两者之间的0,这是我不想要的。

因此,如果有办法做到这一点,或者您可以帮助我,以便我指定一系列索引,例如:[0:40]仅应被屏蔽。

我不想在蒙版后更改数组的尺寸。另外,--的存在对我的目的没有任何影响。

1 个答案:

答案 0 :(得分:3)

您可以使用布尔索引或手动迭代。前者对于小型阵列更有效;后者用于两边都有少量范围外值的大型阵列。

布尔索引

x = np.array([0, 0, 0, 2, 3, 51, 34, 1, 23, 32, 32, 52, 0, 0, 0])

start = (x > 50).argmax()
end = len(x) - (x[::-1] > 50).argmax()

print(x[start: end])

[51 34  1 23 32 32 52]

手动迭代

next与生成器表达式和enumerate一起使用:

start = next(idx for idx, val in enumerate(x) if val > 50)
end = len(x) - next(idx for idx, val in enumerate(reversed(x)) if val > 50)

print(x[start: end])

[51 34  1 23 32 32 12]

掩盖

如果您希望将范围外的值替换为np.nan,则可以进行相应分配,记住首先要转换为float,因为NaN的值是float

x = x.astype(float)
x[:start] = np.nan
x[end:] = np.nan

print(x)

array([nan, nan, nan, nan, nan, 51., 34.,  1., 23., 32., 32., 52., nan, nan, nan])