Python索引分配:无法将掩码为true的6个输出值分配为3个输入值

2024-04-23 15:33:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图制作一个与源数组形状相同的零数组。然后修改第二个数组中与第一个数组中的特定值相对应的每个值

如果我只是替换一个值,这就足够简单了。以下是一个玩具示例:

import numpy as np

arr1 = np.array([[1,2,3],[3,4,5],[1,2,3]])
arr2 = np.array([[0,0,0],[0,0,0],[0,0,0]])

arr2[arr1==1] = -1

这将按预期工作,arr2将为:

[[-1,0,0],
 [ 0,0,0],
 [-1,0,0]]

但我想换一整排。类似这样的内容替换了上面示例代码的最后一行:

arr2[arr1==[3,4,5]] = [-1,-1,-1]

当我这样做时,它也会按预期工作,arr2将是:

[[ 0, 0, 0],
 [-1,-1,-1],
 [ 0, 0, 0]]

但当我试图用以下内容替换示例代码的最后一行时:

arr2[arr1==[1,2,3]] = [-1,-1,-1]

我希望得到类似于上一次输出的结果,但是第0行和第2行被更改了。但是我得到了以下错误

ValueError: NumPy boolean array indexing assignment cannot assign 3 input values to the 6 
output values where the mask is true

我认为这是因为,与其他示例不同,它必须替换多行。虽然这对我来说似乎很奇怪,因为在简单的单值示例中,替换多个值效果很好

我只是想知道是否有人能向我解释这种行为,因为它有点让人困惑。我对numpy操作的内部工作没有那么丰富的经验。此外,如果有人有任何建议来做我试图以有效的方式完成的事情

在我的现实世界实现中,我正在使用一个非常大的三维数组(一个具有3个颜色通道的图像),如果源图像在相应像素中具有特定的3个颜色值(并且保持[0,0,0]),我希望创建一个新数组,将特定值存储到这三个颜色通道中如果它与我们感兴趣的像素(rgb)不匹配)。我可以在线性时间内检查每一个像素,但如果有很多图像,这可能会有点慢,我只是想知道是否有更好的方法

谢谢大家!


Tags: the代码图像numpy示例颜色np像素
2条回答

这将是一个很好的应用程序^{}

>>> import numpy as np
>>> arr1 = np.array([[1,2,3],[3,4,5],[1,2,3]])
>>> arr2 = np.array([[0,0,0],[0,0,0],[0,0,0]])
>>> np.where(arr1 == [1,2,3], [-1,-1,-1], arr1)
array([[-1, -1, -1],
       [ 3,  4,  5],
       [-1, -1, -1]])

这基本上是“只要条件为真,就使用x参数,然后在其余时间使用y参数”

让我们添加一个“索引”数组:

In [56]: arr1 = np.array([[1,2,3],[3,4,5],[1,2,3]])
    ...: arr2 = np.array([[0,0,0],[0,0,0],[0,0,0]])
    ...: arr3 = np.arange(9).reshape(3,3)

针对1值的测试:

In [57]: arr1==1
Out[57]: 
array([[ True, False, False],
       [False, False, False],
       [ True, False, False]])

它有两个真值:

In [58]: arr3[arr1==1]
Out[58]: array([0, 6])

我们可以像您一样指定一个值,或2个值

使用列表进行测试,列表首先转换为数组:

In [59]: arr1==[3,4,5]
Out[59]: 
array([[False, False, False],
       [ True,  True,  True],
       [False, False, False]])

这有三点是正确的:

In [60]: arr3[arr1==[3,4,5]]
Out[60]: array([3, 4, 5])

因此,它可以像您一样指定一个包含3个值的列表。或者一个标量

In [61]: arr1==[1,2,3]
Out[61]: 
array([[ True,  True,  True],
       [False, False, False],
       [ True,  True,  True]])

这里的测试有6个是真的

In [62]: arr3[arr1==[1,2,3]]
Out[62]: array([0, 1, 2, 6, 7, 8])

所以我们可以指定6个值或一个标量。但您尝试分配3个值

或者我们可以应用all查找与[1,2,3]匹配的行:

In [63]: np.all(arr1==[1,2,3], axis=1)
Out[63]: array([ True, False,  True])
In [64]: arr3[np.all(arr1==[1,2,3], axis=1)]
Out[64]: 
array([[0, 1, 2],
       [6, 7, 8]])

为此,我们可以指定一个(2,3)数组、一个标量、一个(3,)数组或一个(2,1)(根据broadcasting规则):

In [65]: arr2[np.all(arr1==[1,2,3], axis=1)]=np.array([100,200])[:,None]
In [66]: arr2
Out[66]: 
array([[100, 100, 100],
       [  0,   0,   0],
       [200, 200, 200]])

相关问题 更多 >