用链式掩码替换numpy数组元素



考虑一些数组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]]

简短的回答:

  • 你必须找出一种方法来组合蒙版。既然口罩可以"链"起来;我认为没有一种简单的万能替代品。

  • 索引可以是__getitem__呼叫,也可以是__setitem__呼叫。你的最后一个案例是一个集合。

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

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

a是否被修改取决于第一个getiitem产生的结果(view vs copy)。

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

好问题!我的看法:

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

下面的大多数示例显示了在引用数组中的数据时索引的使用。这些示例在对数组进行赋值时也同样有效。有关赋值如何工作的具体示例和解释,请参阅最后的部分。

表示arr[mask]=1正在引用,而arr[mask]正在提取数据并创建副本。

最新更新