Массивы Julia
Массив — это коллекция элементов одного типа данных, расположенных в определённом порядке; он может быть одномерным или многомерным массивом.
Julia поддерживает структуры данных массивов, которые могут хранить упорядоченную коллекцию, размер которой не фиксирован, а элементы могут быть одного или разных типов.
Массивы Julia — это изменяемые типизированные коллекции, используемые для списков, векторов, таблиц и матриц.
Индексные ключи массивов Julia могут быть представлены целыми числами, а размер массива не фиксирован.
Julia предоставляет множество функций, помогающих нам работать с массивами, таких как добавление элементов в массивы, объединение массивов и т. д.
Массивы Julia используют квадратные скобки[...]для указания, а несколько элементов используют запятые,для их разделения.
Синтаксис создания одномерного массива (то есть вектора):
[A, B, C, ...]
Создание одномерных массивов
Следующий пример создаёт простой одномерный массив:
Пример
3-элементный Vector{Int64}:
1
2
3
В приведенном выше примере мы создали одномерный массив, содержащий 3 элемента, каждый элемент — 64-битное целое число, и этот одномерный массив привязан к переменнойarr.
Типы элементов массива также могут быть разными:
Пример
4-элементный Vector{Any}:
1
"EXAMPLE"
2.5
π = 3.1415926535897...
В приведенном выше примере мы создали одномерный массив, содержащий 4 элемента разных типов.pi— это константаπ, каждый элемент — 64-битное целое число, и этот одномерный массив привязан к переменнойarr.
Конечно, можно также принудительно задать тип:
Пример
3-элементный Vector{Int64}:
1
2
3
julia> arr2 = String["Taobao","EXAMPLE","GOOGLE"]
3-элементный Vector{String}:
"Taobao"
"EXAMPLE"
"GOOGLE"
Массив в примере вышеarrограничен только целыми числами,arr2ограничен только строками.
Мы также можем создать пустой массив:
Пример
Int64[]
julia> arr2 = String[]
String[]
К созданному массиву можно обращаться напрямую по значениям индексов. Первое значение имеет индекс 1 (не 0), второе — индекс 2, и так далее. Для последнего можно использоватьend, чтобы обозначить:
Пример
3-элементный Vector{Int64}:
1
2
3
julia> arr[2]
2
julia> arr2 = String["Taobao","EXAMPLE","GOOGLE"]
3-элементный Vector{String}:
"Taobao"
"EXAMPLE"
"GOOGLE"
julia> arr2[1]
"Taobao"
julia> arr2[end]
"GOOGLE"
Указание типов и размерностей массива
Мы также можем использовать следующий синтаксис, чтобы указать тип и размерности массива:
Array{type}(undef, dims...)
undefозначает, что массив не инициализирован.
dims...может быть одним или несколькими кортежами размерностей, либо набором значений, когда размерности передаются как переменные аргументы.
dims...Число обозначает количество элементов; при нескольких размерностях используйте запятые,для их разделения.
Пример
3-элементный Vector{Int64}:
4834342704
4377305096
0
julia> array = Array{Int64}(undef, 3, 3, 3) # представляет трёхмерный массив, с 3 элементами в каждом измерении
3×3×3 Array{Int64, 3}:
[:, :, 1] =
4562265712 0 0
1 0 0
0 0 0
[:, :, 2] =
0 0 0
0 0 0
0 0 0
[:, :, 3] =
0 0 0
0 0 0
0 0 0
В приведённом выше примере мы помещаем тип массива в фигурные скобки{}, undef используется, чтобы задать массив как неинициализированный и не имеющий никакого известного значения; поэтому в выводе мы получаем случайные числа.
Создание двумерных массивов и матриц
Мы можем опустить запятые между элементами массива,или использовать два двоеточия;;, таким образом мы можем создать двумерный массив, как в следующем примере:
Пример
1×4 Matrix{Int64}:
1 2 3 4
julia> [1;; 2;; 3;; 4]
1×4 Matrix{Int64}:
1 2 3 4
Примечание:Вывод в первой строке1×4 Matrix{Int64}:, 1x4 обозначает матрицу с одной строкой и четырьмя столбцами.
Хотя в нём только одна строка, это всё ещё двумерный массив, потому что Julia распознаёт только векторы-столбцы, а не так называемые векторы-строки.
Чтобы добавить ещё одну строку, просто добавьте точку с запятой;, см. следующий пример:
Пример
2×2 Matrix{Int64}:
1 2
3 4
Вы также можете использовать двоеточия:и пробелы для этого, см. следующий пример:
Пример
2×2 Matrix{Int64}:
1 3
2 4
Примечание:Вывод в первой строке2×2 Matrix{Int64}:, 2×2 обозначает матрицу с двумя строками и двумя столбцами.
Мы также можем встроить одномерные массивы одинаковой длины в квадратные скобки[]и разделить их пробелами, чтобы создать двумерный массив:
Пример
2×3 Matrix{Int64}:
1 3 5
2 4 6
2x3представляет массив с двумя строками и тремя столбцами.
Ниже мы гибко используем точки с запятой;и пробелы , чтобы создать двумерный массив с двумя строками и тремя столбцами, а также массив с тремя строками и двумя столбцами:
Пример
2×3 Matrix{Int64}:
1 3 5
2 4 6
julia> [[1 2]; [3 4]; [5 6]]
3×2 Matrix{Int64}:
1 2
3 4
5 6
Использование функций диапазона для создания массивов
Многоточие ...
Вы можете использовать многоточие...для создания массива, как в следующем примере:
Пример
11-элементный Vector{Int64}:
0
1
2
3
4
5
6
7
8
9
10
Функция collect()
Синтаксис функции collect() выглядит следующим образом:
collect(start:step:stop)
start — начальное значение, step — размер шага, stop — конечное значение.
Эта функция возвращает массив.
В следующем примере значение равно 1, шаг равен 2, а конечное значение — 13:
Пример
7-элементный Vector{Int64}:
1
3
5
7
9
11
13
Функция collect() также может указывать тип, со следующим синтаксисом:
collect(element_type, start:step:stop)
В следующем примере создаётся массив чисел с плавающей запятой:
Пример
3-элементный Vector{Float64}:
1.0
3.0
5.0
Функция range()
Функция range() может создавать диапазон и задавать размер шага, что удобно для вызова функцией collect().
Синтаксис функции range() выглядит следующим образом:
range(start, stop, length) range(start, stop; length, step) range(start; length, stop, step) range(;start, length, stop, step)start — начальное значение, step — размер шага, stop — конечное значение, а length — длина.
Пример
1:100
julia> range(1, stop=100)
1:100
julia> range(1, step=5, length=100)
1:5:496
julia> range(1, step=5, stop=100)
1:5:96
julia> range(1, 10, length=101)
1.0:0.09:10.0
julia> range(1, 100, step=5)
1:5:96
julia> range(stop=10, length=5)
6:10
julia> range(stop=10, step=1, length=5)
6:1:10
julia> range(start=1, step=1, stop=10)
1:1:10
Если length не указан, иstop - startне является целым кратным step, то будет сгенерирован диапазон, заканчивающийся перед stop.
julia> range(1, 3.5, step=2) 1.0:2.0:3.0
Создание массивов с помощью range() и collect():
Пример
10-элементный Vector{Int64}:
1
2
3
4
5
6
7
8
9
10
julia> collect(range(1, length=15, stop=150))
15-элементный Vector{Float64}:
1.0
11.642857142857142
22.285714285714285
32.92857142857143
43.57142857142857
54.214285714285715
64.85714285714286
75.5
86.14285714285714
96.78571428571429
107.42857142857143
118.07142857142857
128.71428571428572
139.35714285714286
150.0
Создание массивов с помощью включений и генераторов
Ещё один полезный способ создавать массивы — использовать включения.
Синтаксис включений для массивов выглядит так:
A = [ F(x,y,...) for x=rx, y=ry, ... ]
F(x,y,...) вычисляется для каждого значения переменных x, y и т. д. в заданных списках. Значения можно задавать любым итерируемым объектом, но обычно это диапазоны вроде 1:n или 2:(n-1), либо явные значения массива вроде [1.2, 3.4, 5.7]. Результатом является N-мерный плотный массив, размерности которого получаются конкатенацией размерностей диапазонов переменных rx, ry и т. д., а каждое вычисление F(x,y,...) возвращает скаляр.
Пример
10-элементный Vector{Int64}:
1
4
9
16
25
36
49
64
81
100
Создание двумерного массива:
Пример
10×10 Matrix{Int64}:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Включения также можно записывать без квадратных скобок, создавая объект, называемый генератором.
В следующем примере создаётся массив:
Пример
5-элементный Vector{Int64}:
1
4
9
16
25
Следующее выражение суммирует последовательность без выделения памяти:
Пример
1.6439345666815615
Основные функции массивов Julia
| Функция | Описание |
|---|---|
eltype(A) |
Aтип элементов в |
length(A) |
Aколичество элементов в |
ndims(A) |
Aразмерность |
size(A) |
кортеж, содержащийAкортеж с количеством элементов в каждом измерении |
size(A,n) |
AНет.nколичество элементов в измерении |
axes(A) |
кортеж, содержащийAкортеж допустимых индексов |
axes(A,n) |
Нет.nдиапазон допустимых индексов для измерения |
eachindex(A) |
эффективный итератор для доступа кAкаждой позиции в |
stride(A,k) |
наkшаг по измерению (расстояние в линейном индексе между соседними) |
strides(A) |
содержащий шаг по каждому измерению |
Создание и инициализация в Julia
Julia предоставляет множество функций для создания и инициализации массивов. В следующих функциях аргумент dims ... может быть кортежем, представляющим размерности, или переменным числом целочисленных значений в качестве размерностей. Первый аргумент большинства функций представляет тип элементов T массива. Если тип T опущен, по умолчанию используется Float64.
| Функция | Описание |
|---|---|
Array{T}(undef, dims...) |
Плотный массив, который не инициализированArray |
zeros(T, dims...) |
Массив, заполненный нулямиArray |
ones(T, dims...) |
Массив, все элементы которого равны 1Array |
trues(dims...) |
Массив, каждый элемент которого равенtrueизBitArray |
falses(dims...) |
Массив, каждый элемент которого равенfalseизBitArray |
reshape(A, dims...) |
Массив, содержащий те жеAмассив с теми же данными, но другими размерностями |
copy(A) |
copyA |
deepcopy(A) |
глубокая копия, т.е. копированиеA, и рекурсивное копирование его элементов |
similar(A, T, dims...) |
Массив с таким жеAнеинициализированный массив того же типа (здесь имеются в виду dense, sparse и т. д.), но с указанным типом элементов и размерностями. Второй и третий параметры необязательны; если их опустить, по умолчанию используются тип элементов иAразмерности. |
reinterpret(T, A) |
иAМассив с теми же двоичными данными, но тип элементов —T |
rand(T, dims...) |
СлучайныйArray, значения элементовравномерно распределены в полуоткрытом интервале и подчиняются независимому и одинаковому распределению первого порядка[1] |
randn(T, dims...) |
СлучайныйArray, элементы имеют стандартное нормальное распределение, независимы и одинаково распределены |
Matrix{T}(I, m, n) |
mlinenединичная матрица со столбцами (сначала нужно выполнитьusing LinearAlgebraчтобы использоватьI) |
range(start, stop=stop, length=n) |
fromstartвstopwithnдиапазон линейно распределённых элементов |
fill!(A, x) |
Со значениемxзаполнить массивA |
fill(x, dims...) |
Массив, заполненныйxзаполненныйArray |
zeros()Создает экземпляр массива, начальные значения всех элементов равны 0:
Пример
2×3 Matrix{Int8}:
0 0 0
0 0 0
julia> zeros(Int8, (2, 3))
2×3 Matrix{Int8}:
0 0 0
0 0 0
julia> zeros((2, 3))
2×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0