Учитывая массив следующим образом:
A = Array{Array{Int}}(2,2)
A[1,1] = [1,2]
A[1,2] = [3,4]
A[2,1] = [5,6]
A[2,2] = [7,8]
Тогда у нас есть, что A
— это массив 2×2 с элементами типа Array{Int}
:
2×2 Array{Array{Int64,N} where N,2}:
[1, 2] [3, 4]
[5, 6] [7, 8]
Доступ к записям можно получить, например, A[1,2]
, но A[1,2,2]
не будет работать, поскольку третье измерение отсутствует в A. Однако A[1,2][2]
работает, поскольку A[1,2]
возвращает массив длиной 2.
Тогда возникает вопрос, как лучше преобразовать A
в 3-мерный массив B
, чтобы B[i,j,k]
ссылался на i, j-й массив и k-й элемент в этом массиве. Например. B[2,1,2] = 6
.
Есть простой способ сделать это, используя 3 вложенных цикла и восстанавливая массив поэлементно, но я надеюсь, что есть более удобная конструкция. (Возможно, какое-то применение cat
?)
cat(3,first.(A),last.(A))
также дает ту же матрицу. Если более двух элементов во внутренних векторах, getindex
можно использовать для обобщения этой конструкции. — person Calavoow schedule 10.11.2017
Я понял один способ: B = permutedims(reshape(collect(Iterators.flatten(A)), (2,2,2)), [3,2,1])
, но он очень плохо читается, и я бы предпочел использовать генераторы из ответа @durand ниже. Обобщая ваш ответ: cat(3, map(idx -> getindex.(A, idx),(1:2))...)
может быть нормальным (для подходящих диапазонов). — person Calavoow schedule 10.11.2017
Выражения в вашем комментарии также можно записать: permutedims(reshape(vcat(A...),2,2,2),[2,3,1])
и cat(3,(getindex.(A,i) for i=1:2)...)
— person Calavoow schedule 10.11.2017
Вы можете построить трехмерный массив из A, используя понимание массива
Однако более общим решением было бы перегрузить функцию getindex для массивов с тем же типом A. Это более эффективно, поскольку нет необходимости копировать исходные данные.
Благодаря комментариям Дэна Гетца, я считаю, что следующее работает хорошо и является лаконичным:
где
2
— длина вложенного массива. Это также будет работать для более высоких измерений.permutedims(reshape(collect(Base.Iterators.flatten(A)), (2,2,2)), (2,3,1))
также выполняет свою работу и, кажется, быстрее, чем принятый
cat()
ответ для меня.РЕДАКТИРОВАТЬ: Извините, я только что увидел, что это уже было предложено в комментариях.