numpy - 广播相同形状的多维数组索引

标签 numpy

我有一个 mask 数组,它表示二维二值图像。假设它很简单:

mask = np.zeros((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

假设我想翻转中间左边的元素ninth :

# 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])
mask[np.logical_and(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

(这是我真正处理的约束的简化,在本例中,它不会轻易地表达为 mask[:3,3:6] = 1 之类的内容。考虑任意约束,例如 x % 2 == 0 && y % 3 == 0(如果愿意的话)。)

当两个索引数组形状相同时,Numpy 的行为是成对地获取它们,最终只选择上面的 3 个元素,而不是我想要的 9 个元素。

如何使用适用于不同轴的约束来更新正确的元素?鉴于约束是独立的,我可以通过仅评估约束 N+M 次而不是 N*M 来做到这一点吗?

最佳答案

您无法广播 bool 数组,但您可以使用ix_构造等效的数字索引:

In [330]: np.ix_((y>=3)&(y<6), x<3)                                             
Out[330]: 
(array([[3],
        [4],
        [5]]), array([[0, 1, 2]]))

应用它:

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

尝试直接广播 bool 值会引发错误(索引过多):

arr[((y>=3)&(y<6))[:,None], x<3]

关于numpy - 广播相同形状的多维数组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59168428/

相关文章:

python - 有没有更好的方法来确定 numpy 数组的交叉映射索引

Python:计算多个数组列中的零并有效存储它们

python - 'numpy.ndarray' 对象没有属性 'index'

python - Pandas 中的 Groupby 列并执行计算 (Python)

python - 给定一些索引,如何在索引的 "rest"上索引数组/张量?

python - 具有预定义箱和闭/开区间的箱变量

python - win32com 内存错误 : CreatingSafeArray attempting to insert data into excel

python - 使用numpy优化python函数而不使用for循环

python - 尝试将 MATLAB 数组转换为 Python 数组

python - 在 3D RGB numpy 数组中设置蒙版像素