Numpy 广播相同形状的多维阵列索引

Numpy 广播相同形状的多维阵列索引,numpy,Numpy,我有一个掩码数组,它表示一个二维二进制图像。让我们简单地说: mask=np.zero((9,9),dtype=np.uint8) # 0 0 0 | 0 0 0 | 0 0 0 # 0 0 0 | 0 0 0 | 0 0 0 # 0 0 0 | 0 0 0 | 0 0 0 # ------+-------+------ # 0 0 0 | 0 0 0 | 0 0 0 # 0 0 0 | 0 0 0 | 0 0 0 # 0 0 0 | 0 0 0 | 0 0 0 # ------+-------

我有一个
掩码
数组,它表示一个二维二进制图像。让我们简单地说:

mask=np.zero((9,9),dtype=np.uint8)
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# ------+-------+------
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# ------+-------+------
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
假设我想翻转左边中间的元素:

#0 0 | 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# ------+-------+------
# 1 1 1 | 0 0 0 | 0 0 0
# 1 1 1 | 0 0 0 | 0 0 0
# 1 1 1 | 0 0 0 | 0 0 0
# ------+-------+------
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
我的错误做法是这样的:

x=np.arange(mask.shape[0])
y=np.arange(mask.shape[1])
掩码[np.逻辑_和(y>=3,y<6),x<3]=1
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# ------+-------+------
# 1 0 0 | 0 0 0 | 0 0 0
# 0 1 0 | 0 0 0 | 0 0 0
# 0 0 1 | 0 0 0 | 0 0 0
# ------+-------+------
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0
# 0 0 0 | 0 0 0 | 0 0 0

(这是一个我正在处理的约束的简化,它不容易被表达为“代码>掩码[3,3:6]=1代码/代码>。在这种情况下。考虑约束任意,如<代码> x% 2=0 & & y=3=0</代码>如果你愿意。) 当两个索引数组的形状相同时,Numpy的行为是将它们成对,结果只选择上面的3个元素,而不是我想要的9个


如何使用应用于不同轴的约束更新正确的图元?考虑到约束是独立的,我是否可以通过只计算我的约束N+M次而不是N*M次来实现这一点?

根据您的评论,让我们试试这个更有趣的例子:

mask = np.zeros((90,90), dtype=np.uint8)

# criteria
def f(x,y): return ((x-20)**2 < 50) & ((y-20)**2 < 50)

# ranges
x,y = np.arange(90), np.arange(90)

# meshgrid
xx,yy = np.meshgrid(x,y)

zz = f(xx,yy)

# mask
mask[zz] = 1
plt.imshow(mask, cnap='gray')
mask=np.zero((90,90),dtype=np.uint8)
#标准
def f(x,y):返回((x-20)**2<50)和((y-20)**2<50)
#范围
x、 y=np.arange(90),np.arange(90)
#网格
xx,yy=np.meshgrid(x,y)
zz=f(xx,yy)
#面具
掩码[zz]=1
plt.imshow(蒙版,cnap='gray')
输出:


您不能
广播
布尔数组,但可以使用
ix
构造等价的数值索引:

In [330]: np.ix_((y>=3)&(y<6), x<3)                                             
Out[330]: 
(array([[3],
        [4],
        [5]]), array([[0, 1, 2]]))
试图
广播
布尔值会直接引发错误(
索引太多
):


arr[((y>=3)和(yI可以做一些像
mask[np.logical][u和(y>=3,y<6)[:,np.newaxis]*(x<3)]=1
但这似乎并不理想。尽管看起来很花哨,但上面的内容与
mask[:3,3:6]=1
没有太大区别。谢谢。在我的“真的”问题是,约束更为复杂;约束可能类似于
(y-4)**2<25
,它将对遮罩的抛物线*部分进行索引。因此,这与其说是我试图在这里制作的特定形状,不如说是在不同轴上具有约束的问题。仅供参考,
(y-4)**2银行。我更新了另一个例子,希望能澄清。不过,如果我这样做,我想代码会变得不可读。@rgov更新后的答案与您的问题类似吗?假设它是
(x-20)**2<50
(y-20)**2<50
,而不是单一的约束
(x-20)**2+(y-20)**2-100<0
。这将如何改变你的答案?
In [331]: arr = np.zeros((9,9),int)                                             
In [332]: arr[_330] = 1                                                         
In [333]: arr                                                                   
Out[333]: 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0]])
arr[((y>=3)&(y<6))[:,None], x<3]