如何在 Numpy 中将索引数组转换为掩码数组?

Posted

技术标签:

【中文标题】如何在 Numpy 中将索引数组转换为掩码数组?【英文标题】:How can you turn an index array into a mask array in Numpy? 【发布时间】:2014-10-28 13:40:23 【问题描述】:

在给定范围的情况下,是否可以将索引数组转换为 1 和 0 数组? 即 [2,3] -> [0, 0, 1, 1, 0],范围为 5

我正在尝试自动化这样的事情:

>>> index_array = np.arange(200,300)
array([200, 201, ... , 299])

>>> mask_array = ???           # some function of index_array and 500
array([0, 0, 0, ..., 1, 1, 1, ... , 0, 0, 0])

>>> train(data[mask_array])    # trains with 200~299
>>> predict(data[~mask_array]) # predicts with 0~199, 300~499

【问题讨论】:

scipy 有一个掩码数组模块。它与问题有关。 docs.scipy.org/doc/numpy/reference/maskedarray.html [x in index_array for x in range(500)] 可以做到这一点,但使用 TrueFalse 而不是 1 和 0。 @genisage 您能否发表评论作为答案?我想选择你的。这正是我一直在寻找的东西。谢谢你的回答! numpy.array([boolean_value in indices for x in range(length)], dtype=np.int8) 将适用于一维数组 不确定,如果直接与上面提出的问题一致,但您是否探索过 numpy masked_array docs.scipy.org/doc/numpy-1.13.0/reference/generated/… 以防它有助于进一步探索 【参考方案1】:

这是一种方法:

In [1]: index_array = np.array([3, 4, 7, 9])

In [2]: n = 15

In [3]: mask_array = np.zeros(n, dtype=int)

In [4]: mask_array[index_array] = 1

In [5]: mask_array
Out[5]: array([0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0])

如果掩码始终是范围,则可以消除index_array,并将1 分配给切片:

In [6]: mask_array = np.zeros(n, dtype=int)

In [7]: mask_array[5:10] = 1

In [8]: mask_array
Out[8]: array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0])

如果您想要一个布尔值数组而不是整数,请在创建时更改mask_arraydtype

In [11]: mask_array = np.zeros(n, dtype=bool)

In [12]: mask_array
Out[12]: 
array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False], dtype=bool)

In [13]: mask_array[5:10] = True

In [14]: mask_array
Out[14]: 
array([False, False, False, False, False,  True,  True,  True,  True,
        True, False, False, False, False, False], dtype=bool)

【讨论】:

+1 这也是一个非常好的答案,尤其是如果有人希望他们的 mask_array 是 np.array。 而且比列表推导效率高很多。 用 int 代替 bool 有什么好处吗?我只是想知道为什么当问题要求戴口罩时,答案的顶部不推荐 bool。【参考方案2】:

根据要求,这是一个答案。代码:

[x in index_array for x in range(500)]

会给你一个你要求的掩码,但它会使用布尔值而不是 0 和 1。

【讨论】:

这是 op 最初标记的答案。但是标记它会让其他人反对-3,所以我不得不改变我的标记...... 这个真的很慢:不仅没有矢量化,而且也是 O(n²)。【参考方案3】:

对于单个维度,请尝试:

n = (15,)
index_array = [2, 5, 7]
mask_array = numpy.zeros(n)
mask_array[index_array] = 1

对于多个维度,将您的 n 维索引转换为一维索引,然后使用 ravel:

n = (15, 15)
index_array = [[1, 4, 6], [10, 11, 2]] # you may need to transpose your indices!
mask_array = numpy.zeros(n)
flat_index_array = np.ravel_multi_index(
    index_array,
    mask_array.shape)
numpy.ravel(mask_array)[flat_index_array] = 1

【讨论】:

【参考方案4】:

单行也有一个很好的技巧 - 像这样使用 numpy.in1dnumpy.arange 函数(最后一行是关键部分):

>>> x = np.linspace(-2, 2, 10)
>>> y = x**2 - 1
>>> idxs = np.where(y<0)

>>> np.in1d(np.arange(len(x)), idxs)
array([False, False, False,  True,  True,  True,  True, False, False, False], dtype=bool)

这种方法的缺点是它比 Warren Weckesser 给出的方法慢约 10-100 倍……但它是单线的,可能是也可能不是您正在寻找的。​​p>

【讨论】:

in1d() 方法不是比其他方法提出的解决方案要广泛得多吗?

以上是关于如何在 Numpy 中将索引数组转换为掩码数组?的主要内容,如果未能解决你的问题,请参考以下文章

创建numpy数组,其中值在其他两个相同大小排列的范围内

科学计算基础软件包NumPy入门讲座:掩码数组

科学计算基础软件包NumPy入门讲座:掩码数组

如何为 numpy 数组创建圆形掩码?

numpy 从索引列表创建 2D 掩码 [+ 然后从掩码数组中绘制]

如何在 NumPy 中将 HDF5 2D 数组转换为 1D?