【问题标题】:Apply boolean mask at position to 2D numpy array将位置处的布尔掩码应用于 2D numpy 数组
【发布时间】:2021-07-01 03:48:00
【问题描述】:

我已经四处寻找了一段时间,但找不到具体问题的答案。

假设我有这个 dtype Object 的空 2D numpy 数组和一个布尔掩码:

class Object(object):
    def __repr__(self):
        return "aObj"

a = np.empty((7, 10), dtype=Object)
mask = np.array([[False, True, False], [True, False, True], [True, True, True]])

我想应用此掩码将记录分配给 Object 的实例,给定必须应用此掩码的左上位置:

top_left = (2, 3)
obj = Object()
result = apply_mask(a, mask, top_left, obj)
result

array([[None, None, None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None],
       [None, None, None, None, aObj, None, None, None, None, None],
       [None, None, None, aObj, None, aObj, None, None, None, None],
       [None, None, None, aObj, aObj, aObj, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None]],
      dtype=Object)

如您所见,行索引 2 的第四列设置为 aObject,因为第一个掩码行是 [False, True False],只有第二个索引应该设置为 obj。同样,行索引 3 的第 3 列和第 5 列在掩码的第二行之后设置为 obj[True, False, True]

我一直在查看 numpy.ma 模块,但找不到我一直在寻找的东西。到目前为止,我一直在搞乱np.indeces

yd, xd = np.indices(a.shape)
result = a
result[(xd >= top_left[1]) &
       (xd < top_left[1] + mask.shape[1]) &
       (yd >= top_left[0]) &
       (yd < top_left[0] + mask.shape[0])] = obj

但显然这只会产生obj的矩形,我还没有真正应用蒙版,只是形状。

有什么建议吗?


编辑:一个重要的细节是,如果另一个 Object 实例已经存在于掩码中 False 覆盖的记录之一中,则该实例应该持续存在。请参阅以下示例:

a = np.empty((7, 10), dtype=Object)
a[2 ,3] = Object()
mask = np.array([[False, True, False], [True, False, True], [True, True, True]])
top_left = (2, 3)
result = apply_mask(a, mask, top_left, Object())
result

array([[None, None, None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None],
       [None, None, None, aObj, aObj, None, None, None, None, None],
       [None, None, None, aObj, None, aObj, None, None, None, None],
       [None, None, None, aObj, aObj, aObj, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None]],
      dtype=Object)

这确实让我相信我需要 np.ma 模块,因为那些掩码数组实际上支持 empty 记录。


编辑:

使用切片,我可以在我想要的确切位置分配一个对象数组

result[top_left[1]:top_left[1] + mask.shape[1],
       top_left[0]:top_left[0] + mask.shape[0]] = obj_array

但是这不满足之前编辑中提到的约束。

所以我正在查看掩码数组,我希望使用以下代码它会起作用,但是唉:

obj_mask = np.ma.masked_where(~mask, np.full(mask.shape, obj))
result = a
result[top_left[1]:top_left[1] + mask.shape[1],
       top_left[0]:top_left[0] + mask.shape[0]] = obj_mask
result

array([[None, None, None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None],
       [None, None, aObj, aObj, aObj, None, None, None, None, None],
       [None, None, aObj, aObj, aObj, None, None, None, None, None],
       [None, None, aObj, aObj, aObj, None, None, None, None, None],
       [None, None, None, None, None, None, None, None, None, None]],
      dtype=object)

撇开非一错误不谈,为什么将掩码数据分配给数组时突然可用?

【问题讨论】:

    标签: python numpy multidimensional-array mask


    【解决方案1】:

    我找到了答案!在编辑中我已经非常接近了。

    off-by-one 错误是由索引被交换的事实引起的,我必须使用 np.ma.compressed 方法应用对象掩码。

    全文:

    class Object(object):
        def __repr__(self):
            return "aObj"
    
    a = np.empty((7, 10), dtype=Object)
    a[2, 3] = Object()
    mask = np.array([[False, True, False], [True, False, True], [True, True, True]])
    top_left = (2, 3)
    obj = Object()
    a
    
    array([[None, None, None, None, None, None, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None],
           [None, None, None, aObj, None, None, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None]],
          dtype=object)
    

    我添加了一个对象以表明它在应用蒙版后仍然存在。

    obj_mask = np.ma.masked_where(~mask, np.full(mask.shape, obj))
    obj_mask
    
    masked_array(
      data=[[--, aObj, --],
            [aObj, --, aObj],
            [aObj, aObj, aObj]],
      mask=[[ True, False,  True],
            [False,  True, False],
            [False, False, False]],
      fill_value='?',
      dtype=object)
    

    蒙版的创建方式与编辑相同。

    result = a
    result[top_left[0]:top_left[0] + mask.shape[0],
           top_left[1]:top_left[1] + mask.shape[1]][~obj_mask.mask] = np.ma.compressed(obj_mask)
    result
    
    array([[None, None, None, None, None, None, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None],
           [None, None, None, aObj, aObj, None, None, None, None, None],
           [None, None, None, aObj, None, aObj, None, None, None, None],
           [None, None, None, aObj, aObj, aObj, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None],
           [None, None, None, None, None, None, None, None, None, None]],
          dtype=object)
    

    如您所见,所有值都已应用。

    最后:

    >>> a[2, 3] == a[2, 4]
    False
    
    >>> a[2, 4] == a[3, 3]
    True
    

    正如预期的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      • 2020-04-23
      • 2020-05-09
      相关资源
      最近更新 更多