【问题标题】:Julia comprehension: convert a 2d array of matrices to a 2d matrixJulia 理解:将二维矩阵数组转换为二维矩阵
【发布时间】:2019-07-17 21:58:47
【问题描述】:

我正在使用 Julia 理解来实现以下目标:

给定一个矩阵 A = [1 2; 3 4],

我想把它扩展成

B = 
[1, 1, 1, 2, 2; 
 1, 1, 1, 2, 2;
 1, 1, 1, 2, 2;
 3, 3, 3, 4, 4;
 3, 3, 3, 4, 4]. 

现在我正在这样做

ns = [3, 2]
B = [fill(B[i, j], ns[i], ns[j]) for i = 1:2, j = 1:2]

但是,它没有得到一个 5x5 矩阵,而是给了我:

2×2 Array{Array{Int64,2},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 0]

那么我应该如何将这个二维矩阵数组转换为二维矩阵呢?还是有其他方法可以进行我需要的扩展?

【问题讨论】:

    标签: julia


    【解决方案1】:

    这里有两种示例方法(第一种使用您的方法,第二种不生成中间矩阵):

    julia> A = [1 2; 3 4]
    2×2 Array{Int64,2}:
     1  2
     3  4
    
    julia> ns = [3, 2]
    2-element Array{Int64,1}:
     3
     2
    
    julia> hvcat(2, [fill(A[j, i], ns[j], ns[i]) for i = 1:2, j = 1:2]...)
    5×5 Array{Int64,2}:
     1  1  1  2  2
     1  1  1  2  2
     1  1  1  2  2
     3  3  3  4  4
     3  3  3  4  4
    
    julia> nsexpand = reduce(vcat, (fill(k, ns[k]) for k in axes(ns, 1)))
    5-element Array{Int64,1}:
     1
     1
     1
     2
     2
    
    julia> [A[i, j] for i in nsexpand, j in nsexpand]
    5×5 Array{Int64,2}:
     1  1  1  2  2
     1  1  1  2  2
     1  1  1  2  2
     3  3  3  4  4
     3  3  3  4  4
    

    编辑

    这是一个额外的例子:

    julia> A = [1 4 7 10
                2 5 8 11
                3 6 9 12]
    3×4 Array{Int64,2}:
     1  4  7  10
     2  5  8  11
     3  6  9  12
    
    julia> hvcat(3, A...)
    4×3 Array{Int64,2}:
      1   2   3
      4   5   6
      7   8   9
     10  11  12
    
    julia> vec(A)
    12-element Array{Int64,1}:
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
    

    所以:

    • 第一个参数告诉您要生成多少
    • hvcatv 之前有 h 所以它需要元素 row-wise
    • 然而数组存储列col-wise

    因此实际上您必须创建临时数组作为目标的转置(因为hvcat 将使用其来创建目标数组的) .实际上这只是一个巧合 - hvcat 不知道您的原始元素存储在矩阵中(它将它们作为调用的位置参数,当时它们存储在矩阵中的事实由于@而丢失了987654328@操作)。

    【讨论】:

    • 谢谢!正是我正在寻找的。但是,我不明白数字“2”作为hvcat 的第一个参数的作用。文档说“第一个参数指定要在每个块行中连接的参数数量。”。如果我理解正确,那么我希望hvcat(2, [fill(A[i, j], ns[i], ns[j]) for i = 1:2, j = 1:2]) 也可以工作,因为在每个块行中还有两个要连接的参数。但它没有,并引发以下错误:ArgumentError: number of arrays 1 is not a multiple of the requested number of block columns 2.
    • 我将对答案进行编辑,以便您清楚地看到发生了什么。