【问题标题】:Replacing numpy array elements with chained masks用链式掩码替换 numpy 数组元素
【发布时间】:2021-05-22 19:32:41
【问题描述】:

考虑一些数组arr 和高级索引掩码mask

import numpy as np

arr = np.arange(4).reshape(2, 2)
mask = A < 2

使用高级索引创建数组的新副本。因此,不能将掩码与附加掩码“链接”,甚至不能使用基本切片操作来替换数组元素:

submask = [False, True]
arr[mask][submask] = -1  # chaining 2 masks
arr[mask][:] = -1  # chaining a mask with a basic slicing operation

print(arr)
[[0 1]
 [2 3]]

我有两个相关的问题:

1/ 使用链式掩码替换数组元素的最佳方法是什么?

2/ 如果高级索引返回一个数组的副本,为什么下面会起作用?

arr[mask] = -1

print(arr)
[[-1 -1]
 [ 2  3]]

【问题讨论】:

    标签: python numpy numpy-ndarray numpy-slicing


    【解决方案1】:

    简短的回答:

    • 你必须想出一种组合面具的方法。由于面具可以以不同的方式“链接”,我认为没有简单的通用替代品。

    • 索引可以是__getitem__ 调用,也可以是__setitem__。您的最后一个案例是一个集合。

    使用链式索引,a[mask1][mask2] =value 被翻译成

    a.__getitem__(mask1).__setitem__(mask2, value)
    

    a 是否被修改取决于第一个 getitem 生成的内容(视图与副本)。

    In [11]: arr = np.arange(4).reshape(2,2)
    In [12]: mask = arr<2
    In [13]: mask
    Out[13]: 
    array([[ True,  True],
           [False, False]])
    In [14]: arr[mask]
    Out[14]: array([0, 1])
    

    使用列表或数组进行索引可能会保留维数,但像这样的布尔值会返回一维数组,即掩码为真的项目。

    在您的示例中,我们可以调整 mask(细节可能因第二个掩码的意图而异):

    In [15]: mask[:,0]=False
    In [16]: mask
    Out[16]: 
    array([[False,  True],
           [False, False]])
    In [17]: arr[mask]
    Out[17]: array([1])
    In [18]: arr[mask] += 10
    In [19]: arr
    Out[19]: 
    array([[ 0, 11],
           [ 2,  3]])
    

    或掩码的逻辑组合:

    In [26]: (np.arange(4).reshape(2,2)<2)&[False,True]
    Out[26]: 
    array([[False,  True],
           [False, False]])
    

    【讨论】:

    • 我接受了一般性,但请参阅其他答案以获取有关如何链接可能在某些情况下有效的掩码的灵感。
    • 我为您的第一个示例添加了一种可能性。
    【解决方案2】:

    几个好问题!我的看法:

    1. 我会这样做:
    x,y=np.where(mask)
    arr[x[submask],y[submask]] = -1
    
    1. 来自official document

    以下大多数示例显示了在引用数组中的数据时使用索引。这些示例在分配给数组时同样有效。有关分配如何工作的具体示例和说明,请参阅最后的部分。

    这意味着arr[mask]=1 是引用,而arr[mask] 是提取数据并创建一个副本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-02
      • 2021-07-04
      • 2013-11-27
      • 2018-03-30
      • 1970-01-01
      • 2015-10-02
      • 2017-12-05
      • 2021-07-04
      相关资源
      最近更新 更多