добавить массив в виде столбца в предварительно инициализированную матрицу - PullRequest
1 голос
/ 04 мая 2019

Я хочу использовать индексирование для заполнения предварительно инициализированной матрицы результатами моего массива для вывода цикла:

  A = Float64.(reshape(1.0:81.0,9,9))
  # initialize output
  B = zeros(Int64, 2, 9)
  j = 1
  for j in 1:size(A,2) # loop cols
    out = [sum(A[:,j]),j]
    out = reshape(out,2,1) # make column to append
    # append out to the B
    global B = hcat(B,out) # this grows...
  end

Я инициализировал B = zeros(Int64, 2, 9)

ту же яркость, что и ожидаемый результат операции sum.

в моем примере с реальным миром - я перебираю j, столбцы и, i строки - затем получается массив ... вместо того, чтобы использовать hcat() для добавления массива в мой вывод, могу ли я сделать это с помощью индексации?

В приведенном выше примере используется hcat(), который затем будет добавлен к существующему B, чтобы он рос. С тех пор я попробовал initializg со строками 2 и cols 0, поэтому hcat() строит, чтобы исправить вывод dim:

B = zeros(Int64, 2, 0)

Я сомневаюсь, будет ли hcat() эффективным с точки зрения памяти (извините, например, с помощью global) - если я не смог сделать это с индексированием, я могу заполнить его для другого внутреннего цикла в моем [i, j]. Но, возможно, у кого-то есть способ добавить массив в виде столбца к существующим предварительно инициализированным выводам?

1 Ответ

2 голосов
/ 04 мая 2019

Рекомендуется предварительно выделить B и заполнить его позже. Я обертываю код в функцию, поскольку она упрощает бенчмаркинг:

function f2()
    A = reshape(1:81,9,9)
    B = zeros(Int64, 2, 9 + size(A,2))
    for j in 1:size(A,2) # loop cols
        B[:, j + 9] .= (sum(view(A, :, j)), j)
    end
    B
end

Ваш старый код:

function f1()
    A = Float64.(reshape(1.0:81.0,9,9))
    B = zeros(Int64, 2, 9)
    j = 1
    for j in 1:size(A,2) # loop cols
        out = [sum(A[:,j]),j]
        out = reshape(out,2,1) # make column to append
        # append out to the B
        B = hcat(B,out)
    end
    B
end

А вот и сравнение:

julia> @btime f1()
  8.567 μs (83 allocations: 7.72 KiB)
2×18 Array{Float64,2}:
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  45.0  126.0  207.0  288.0  369.0  450.0  531.0  612.0  693.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   1.0    2.0    3.0    4.0    5.0    6.0    7.0    8.0    9.0

julia> @btime f2()
  73.662 ns (1 allocation: 368 bytes)
2×18 Array{Int64,2}:
 0  0  0  0  0  0  0  0  0  45  126  207  288  369  450  531  612  693
 0  0  0  0  0  0  0  0  0   1    2    3    4    5    6    7    8    9

И вы можете видеть, что разница очень значительна.

Еще несколько незначительных комментариев к вашему исходному коду:

  • нет необходимости вызывать Float64. на reshape(1.0:81.0,9,9), объект уже содержит элементы, которые имеют Float64 значения
  • в вашем коде было несоответствие, которое изначально B удерживалось Int64 и A удерживалось Float64 - я сделал это непротиворечивым (я выбрал Int64, но с тем же успехом вы могли бы использовать Float64)
  • sum(A[:,j]) излишне выделен новый объект; быстрее использовать view
  • Вам не нужно было вызывать reshape(out,2,1) на out до hcat, поскольку векторы уже рассматриваются как столбчатые объекты
...