python - 加快深度的 numpy 整数数组索引

标签 python numpy vectorization

假设我有一个数组

 [[0 2 1]
  [1 0 1]
  [2 1 1]]

我想把它转换成张量形式

[[[1 0 0]
  [0 1 0]
  [0 0 0]]
 [[0 0 1]
  [1 0 1]
  [0 1 1]]
 [[0 1 0]
  [0 0 0]
  [1 0 0]]]

其中每个深度层(索引 i)是一个二进制掩码,显示 i 在输入中出现的位置。

我已经为此编写了代码,它可以正常工作,但速度太慢,无法使用。我可以用另一个向量化操作替换此函数中的循环吗?

def im2segmap(im, depth):
    tensor = np.zeros((im.shape[0], im.shape[1], num_classes))

    for c in range(depth):
        rows, cols = np.argwhere(im==c).T
        tensor[c, rows, cols] = 1

    return tensor

最佳答案

使用broadcasting -

(a==np.arange(num_classes)[:,None,None]).astype(int)

或者与builtin外部比较——

(np.equal.outer(range(num_classes),a)).astype(int)

如果必须使用 int 数据类型或通过跳过 int 转换保留为 boolean,请使用 uint8完全是为了进一步插入。

sample 运行-

In [42]: a = np.array([[0,2,1],[1,0,1],[2,1,1]])

In [43]: num_classes = 3 # or depth

In [44]: (a==np.arange(num_classes)[:,None,None]).astype(int)
Out[44]: 
array([[[1, 0, 0],
        [0, 1, 0],
        [0, 0, 0]],

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

       [[0, 1, 0],
        [0, 0, 0],
        [1, 0, 0]]])

要将 depth/num_classes 作为第三个 dim,扩展输入数组,然后与范围数组进行比较 -

(a[...,None]==np.arange(num_classes)).astype(int)
(np.equal.outer(im, range(num_classes))).astype(int)
(np.equal.outer(im, range(num_classes))).astype(np.uint8) # lower prec

关于python - 加快深度的 numpy 整数数组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50022540/

相关文章:

python - 计算三个矩阵的最大值和最小值

python - 如何选择 NumPy 数组中除索引序列之外的所有元素

R - 是否有一种矢量化方式/预制函数可以快速生成两个向量之间的唯一集?

c++ - 仅当循环中更新的变量是本地变量时才优化计算

python - 外键在 django 中不起作用

python - 如何将坐标从列表同时传递到多个步进电机,而不是按顺序?

python - 在图形工具中绘制图形时,仅出现顶点,没有边缘

python - 使用Python API读/写Mysql DB

c++ - 如何将数组从c++传递到python函数并将python返回的数组检索到c++

python - 将数组元素的邻居广义堆叠到 3D 数组中