【问题标题】:How to convert an array index to/from a mask如何将数组索引转换为掩码/从掩码转换
【发布时间】:2022-10-18 04:26:41
【问题描述】:

假设我有一个数组,例如:

a1 = np.array([.1, .2, 23., 4.3, 3.2, .1, .05, .2, .3, 4.2, 7.6])

我过滤掉并创建一个所有小于 1 的值的掩码,例如:

a2 = a1[a1 >= 1]
a2_mask = np.ma.masked_where(a1 < 1, a1)

然后搜索特定值:

a2_idx = np.where(a2==3.2)[0][0]

我如何将该索引转换为原始数组中的相应索引?

例如

>>> a2_idx
2
>>> a1_idx = reframe_index(a2_idx, a2_mask)
>>> a1_idx
4

我天真的实现是:

def reframe_index(old_idx, mask):
    cnt = 0
    ref = 0
    for v in mask:
        if not isinstance(v, (int, float)):
            cnt += 1
        else:
            if ref == old_idx:
                return ref + cnt
            ref += 1

Numpy 是否有更有效的方法来做到这一点?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    a2 是一个副本,所以它和a1 之间没有链接——除了一些值。

    In [19]: a2
    Out[19]: array([23. ,  4.3,  3.2,  4.2,  7.6])
    In [20]: np.nonzero(a2 == 3.2)
    Out[20]: (array([2]),)
    In [21]: a2[2]
    Out[21]: 3.2
    

    a2_maskmask,也就是 a1&lt;1,确实为我们提供了一种查找 a1 对应元素的方法:

    In [22]: a2_mask = np.ma.masked_where(a1 < 1, a1)
    In [23]: a2_mask
    Out[23]: 
    masked_array(data=[--, --, 23.0, 4.3, 3.2, --, --, --, --, 4.2, 7.6],
                 mask=[ True,  True, False, False, False,  True,  True,  True,
                        True, False, False],
           fill_value=1e+20)
    In [24]: a2_mask.compressed()
    Out[24]: array([23. ,  4.3,  3.2,  4.2,  7.6])
    In [25]: a2_mask.mask
    Out[25]: 
    array([ True,  True, False, False, False,  True,  True,  True,  True,
           False, False])
    In [26]: np.nonzero(~a2_mask.mask)
    Out[26]: (array([ 2,  3,  4,  9, 10]),)
    In [27]: np.nonzero(~a2_mask.mask)[0][2]
    Out[27]: 4
    In [28]: a1[4]
    Out[28]: 3.2
    

    因此,您首先需要用于选择 a2 的掩码或索引。 a2 本身没有信息。

    In [30]: np.nonzero(a1>=1)
    Out[30]: (array([ 2,  3,  4,  9, 10]),)
    In [31]: np.nonzero(a1 >= 1)[0][2]
    Out[31]: 4
    

    【讨论】:

      【解决方案2】:

      我最近也有类似的问题,所以我发了haggis.npy_util.unmasked_index1.对于您相对简单的情况,此函数有很多过度杀伤力,因为它旨在对任意数量的维度进行操作。话虽如此,鉴于

      >>> arr = np.array([.1, .2, 23., 4.3, 3.2, .1, .05, .2, .3, 4.2, 7.6])
      

      >>> mask = arr >= 1
      >>> mask
      array([False, False,  True,  True,  True, False, False, False, False,
             True,  True])
      

      你可以做类似的事情

      >>> idx = unmasked_index(np.flatnonzero(arr[mask] == 3.2), mask)
      >>> idx
      array([4])
      

      如果您需要它,还有一个反函数 haggis.npy_util.masked_index 将多维输入数组中的位置转换为其在掩码数组中的索引。

      1免责声明:我是哈吉斯的作者。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-22
        • 2014-10-28
        • 2021-07-15
        • 2021-09-18
        • 2019-01-19
        • 1970-01-01
        • 2021-03-01
        • 2017-06-29
        相关资源
        最近更新 更多