Двумерные (многомерные) массивы

Кроме того, что в конструкторе Array{Any,1}() можно заменить единичку на другую цифру, для создания многомерных массивов можно можно использовать синтаксические конструкции, описанные ниже.

Я пытаюсь навести порядок в своей голове и запомнить этот путанный синтаксис. Так что, я вывел себе правила для запоминания. Придется немного вернуться к одноразмерным массивам.

  • Одномерный массив (он же вектор) - это "вертикальный" массив.

Это имеет значение, т.к. обход всех элементов двумерного массива эффективен, когда он происходит сначала по внутренней (вертикальной) размерности, а потом по внешней (горизонтальной). Так они устроены. Второе. Если обращаться к двумерному массиву, как к простой коллекции, т.е. последовательно, то именно в таком порядке и будут получены элементы. Как мы увидим ниже, REPL отображает массивы, тоже, сначала - по вертикали.

  • Элементы одномерного массива разделяются запятой.

Вот, как он выглядит:

julia> [1, 2]
2-element Array{Int64,1}:
 1
 2
  • Второе измерение идет по горизонтали.

Это наращивание количества колонок. Оно будет внешним циклом последовательного обхода. Таким образом, массив 3x2 - это "три строки (ряда)" на "две колонки".

  • Колонки разделяются пробелом.

Вырожденный случай двумерного массива, массив 1x3:

julia> [1 2 3]
1×3 Array{Int64,2}:
1  2  3

Итак, горизонтальная конкатенация:

julia> [[1,2,3] [4,5,6]]
3×2 Array{Int64,2}:
 1  4
 2  5
 3  6

Вертикальная конкатенация.

Все становится сложнее, если пробел заменить переносом строки:

julia> [[1,2,3]
        [4,5,6]]
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6

Задумка авторов такова. Пусть, мы имеем два массива:

julia> a1=[1,2,3] 
3-element Array{Int64,1}:
 1
 2
 3

julia> a2=[3,4,5]
3-element Array{Int64,1}:
 3
 4
 5

Тогда, оъединить их в двумерный можно так (горизонтально):

julia> [a1 a2]
3×2 Array{Int64,2}:
 1  3
 2  4
 3  5

или так (вертикально), в данном случае - в одно измерение:

julia> [a1
       a2]
6-element Array{Int64,1}:
 1
 2
 3
 3
 4
 5

Пусть, это будет правило:

  • перенос строки добавляет новые строки (ряды)

Если же поставить между ними запятую (не важно, с переносом строки или без), то конкатенации не будет: мы получим одномерный массив массивов. Т.е. мы просто перечисляем элементы вектора, а их тип - вопрос второстепенный. Точно так же мы могли бы заполнить вектор любыми другими типами. Итак, еще одно правило:

  • запятая говорит: "внутрь элементов не заглядываем":
julia> [a1, a2]
2-element Array{Array{Int64,1},1}:
 [1,2,3]
 [3,4,5]

Теперь красивый синтаксис "что на коробке - то и в коробке":

julia> [[1 2 3]
        [3 4 5]]
2×3 Array{Int64,2}:
 1  2  3
 3  4  5

Проще:

julia> [1 2 3
        3 4 5]
2×3 Array{Int64,2}:
 1  2  3
 3  4  5

С вышеперечисленными правилами не конфликтует.

А для случаев, когда нужно все это записать в одну строку -

  • вместо переноса строки можно использовать точку с запятой:
julia> [[1 2 3]; [3 4 5]]
2×3 Array{Int64,2}:
 1  2  3
 3  4  5

Оно же:

julia> [1 2 3; 3 4 5]
2×3 Array{Int64,2}:
 1  2  3
 3  4  5

И, для закрепления, вырожденный случай:

julia> [1;2;3]
3-element Array{Int64,1}:
 1
 2
 3

А чем это отличается от: [1,2,3] ? А тем, что точка с запятой заглядывает внутрь элементов, а запятая - нет.

Обратиться к одиночным элементам двумерного массива можно указывая индексы через запятую внутри квадратных скобок:

julia> a2x = [[2,3] [4,5]]
2×2 Array{Int64,2}:
 2  4
 3  5

julia> a2x[1,2]
4

Доступ к срезу массива таков:

julia> view(a2x,:,:)
2×2 SubArray{Int64,2,Array{Int64,2},Tuple{Colon,Colon},true}:
 2  4
 3  5

julia> view(a2x,:)
4-element SubArray{Int64,1,Array{Int64,1},Tuple{Colon},true}:
 2
 3
 4
 5

julia> view(a2x,1,:)
2-element SubArray{Int64,1,Array{Int64,2},Tuple{Int64,Colon},true}:
 2
 4

julia> view(a2x,:,2)
2-element SubArray{Int64,1,Array{Int64,2},Tuple{Colon,Int64},true}:
 4
 5

SubArray ссылается на родительский массив без копирования его элементов.

К двумерному массиву можно обращаться последовательно, как к одномерному:

julia> a2x[3]
4

julia> for i in a2x println(i) end
2
3
4
5

Двумерный массив отличается от массива массивов, вот, для наглядности, массив массивов:

julia> aa = [[x, x*2] for x in 1:2]
2-element Array{Array{Int64,1},1}:
 [1,2]
 [2,4]

обращение к элементам здесь другое:

julia> aa[2][2]
4

Синтаксис горизонтальной, вертикальной и горизонтально-вертикальной конкатенации раскрывается в вызовы соответствующих функций hcat, vcat, hvcat. Вместо использования квадраных скобок, можно пользоваться ими. Вы можете получить подробную справку по ним в REPL.

results matching ""

    No results matching ""