将 2D 矩阵的 1 广播到 1-hot 3D 矩阵

Broadcasting 1s of a 2D matrix to a 1-hot 3D matrix

给定 2D 矩阵 A,我如何广播它来创建 3D 矩阵 B

A = [[1 1 1 1 0];[0 0 0 0 1]]
B = cat([[1 0 0 0 0];[0 0 0 0 0]],
        [[0 1 0 0 0];[0 0 0 0 0]], 
        [[0 0 1 0 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 1]], dims=3)

我已经为这个问题标记了 numpy-broadcasting,因为当我使用 Julia 1.2.0 时,Julia 广播以 NumPy 广播为模型,因此可能有类似的共享解决方案。

我不确定这是否符合您对 "broadcasting" 的定义,但获得您想要的内容的自然方式是:

julia> cat(diagm.(getindex.(Ref(A), 1:2, :))..., dims=3)
5×5×2 Array{Int64,3}:
[:, :, 1] =
 1  0  0  0  0
 0  1  0  0  0
 0  0  1  0  0
 0  0  0  1  0
 0  0  0  0  0

[:, :, 2] =
 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

或者如果您实际上更愿意避免广播(在这种情况下这似乎更简单):

julia> cat((diagm(A[i, :]) for i in 1:2)..., dims=3)
5×5×2 Array{Int64,3}:
[:, :, 1] =
 1  0  0  0  0
 0  1  0  0  0
 0  0  1  0  0
 0  0  0  1  0
 0  0  0  0  0

[:, :, 2] =
 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

编辑

鉴于您的评论,获得您想要的内容的最简单方法是使用理解:

[j==k ? A[i,j] : 0 for i in axes(A, 1), j in axes(A, 2), k in axes(A, 2)]

这和使用广播一样,但是比较难看:

((i,j,k) -> j==k ? A[i,j] : 0).(axes(A, 1), reshape(axes(A, 2), 1, :), reshape(axes(A, 2), 1, 1, :))

((i,j,k) -> j==k * A[i,j]).(axes(A, 1), reshape(axes(A, 2), 1, :), reshape(axes(A, 2), 1, 1, :))