【问题标题】:Masking only a certain range of indices in numpy在 numpy 中仅屏蔽特定范围的索引
【发布时间】:2019-02-27 05:50:08
【问题描述】:

我有一个 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] 只应该被屏蔽。

我不想在屏蔽后更改数组的维度。此外,-- 的存在不会影响我的目的。

【问题讨论】:

  • 屏蔽应该达到什么效果?我没有看到预期的输出。
  • 已进行更改。
  • 第 29 和第 30 位的两个ones 呢?
  • @a_ran 只需提及阈值 (50),不要将自己和他人与提及的零混淆。
  • @jpp 的布尔索引解决方案(稍作调整)将选择应该与排除末端相同的中间。

标签: python arrays numpy masking masked-array


【解决方案1】:

您可以使用布尔索引或手动迭代。前者对小数组效率更高;后者用于具有少量超出范围值的大型数组。

布尔索引

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])

【讨论】:

  • 我不想改变数组的维度。我已经把预期的输出。
  • @a_ran, -- 不是数字数组中的有效元素,我已编辑以包含替换为 np.nan 的解决方案。
  • 我同意,但这对于我想要实现的目标并不重要。
  • @jpp 我从问题中的提示中收集到这一点,但 OP 似乎正在寻找在掩码数组中操作掩码。在这种情况下,-- 似乎是有效的打印输出。
猜你喜欢
  • 2022-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2018-05-11
相关资源
最近更新 更多