В Julia найдите максимум для каждой позиции набора массивов

#arrays #julia

Вопрос:

У меня есть массив, подобный этому

 a = [ rand(1:20,3)  for i in 1:2,j in 1:3]
2×3 Array{Array{Int64,1},2}:
2×3 Array{Array{Int64,1},2}:
 [8, 13, 1]   [12, 4, 9]  [13, 18, 7]
 [3, 19, 20]  [8, 3, 11]  [10, 9, 12]
 

Я хотел бы, чтобы для каждой строки был получен массив 1 х 3 с максимумом в каждой позиции вдоль строки. Например, в приведенном выше примере:

 [13,18,9]
[10,19,20]
 

(этот вопрос также был задан на другой платформе: https://discourse.julialang.org/t/find-the-maximum-for-each-position-of-a-set-of-arrays/62155/3 )

Комментарии:

1. Я просто хотел бы добавить, что вы можете извлечь выгоду из рефакторинга своего кода. Эти типы структур данных обычно поступают из MATLAB, где пользователи любят упаковывать все в ячейки массивов ячеек массивов до бесконечности. Это плохо сказывается на производительности в целом, поэтому, если бы вы могли упростить свой код, чтобы избежать вложенности структур, вы могли бы значительно ускорить работу без промежуточного выделения памяти.

Ответ №1:

Если я правильно понял ваш вопрос, вы можете просто векторизовать maximum :

 julia> a = [ rand(1:20,3)  for i in 1:2,j in 1:3]
2×3 Matrix{Vector{Int64}}:
 [13, 10, 10]  [14, 8, 9]    [15, 8, 5]
 [18, 18, 7]   [19, 10, 17]  [17, 8, 7]

julia> maximum.(a)
2×3 Matrix{Int64}:
 13  14  15
 18  19  17
 

Если вы хотите, чтобы вектор строк использовался collect в сочетании с eachrow :

 julia> collect(eachrow(maximum.(a)))
2-element Vector{SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:
 [13, 14, 15]
 [18, 19, 17]
 

Ответ №2:

Ответы из связанной темы обсуждения:

 julia> a = [  [[8, 13, 1]]   [[12, 4, 9]]  [[13, 18, 7]]
        [[3, 19, 20]]  [[8, 3, 11]]  [[10, 9, 12]]  ];  # as in question

julia> res1 = [max.(row...) for row in eachrow(a)]
2-element Vector{Vector{Int64}}:
 [13, 18, 9]
 [10, 19, 20]

julia> res1 == [vec(maximum(reduce(hcat, row), dims=2)) for row in eachrow(a)]
true

julia> using TensorCast

julia> res1 == @reduce res[i][k] := maximum(j) a[i,j][k]
true
 

Сравнить:

 julia> res2 = collect.(eachrow(maximum.(a)))
2-element Vector{Vector{Int64}}:
 [13, 12, 18]
 [20, 11, 12]

julia> res2 == [maximum.(b) for b in eachrow(a)]
true

julia> res2 == @reduce res[i][j] := maximum(k) a[i,j][k]
true