介紹 Julia/陣列和元組
在 Julia 中,相關專案的組通常儲存在陣列、元組或字典中。陣列可用於儲存向量和矩陣。本節重點介紹陣列和元組;有關字典的更多資訊,請參閱 字典和集合。
陣列是有序的元素集合。它通常用方括號和逗號分隔的專案表示。您可以建立完整的或空的陣列,以及包含不同型別值的陣列或僅包含特定型別的陣列。
在 Julia 中,陣列用於列表、向量、表格和矩陣。
一維陣列充當向量或列表。二維陣列可以用作表格或矩陣。三維和更多維陣列類似地被認為是多維矩陣。
以下是建立簡單一維陣列的方法
julia> a = [1, 2, 3, 4, 5]
5-element Array{Int64,1}:
1
2
3
4
5
Julia 通知您(“5-element Array{Int64,1}”)您建立了一個包含 5 個元素的一維陣列,每個元素都是一個 64 位整數,並將變數 a 繫結到它。請注意,智慧應用於此過程:例如,如果其中一個元素看起來像一個浮點數,您將獲得一個 Float64 陣列
julia> a1 = [1, 2, 3.0, 4, 5]
5-element Array{Float64,1}:
1.0
2.0
3.0
4.0
5.0
字串也類似
julia> s = ["this", "is", "an", "array", "of", "strings"]
6-element Array{String,1}:
"this"
"is"
"an"
"array"
"of"
"strings"
返回一個字串陣列,以及
julia> trigfuns = [sin, cos, tan]
3-element Array{Function,1}:
sin
cos
tan
返回一個 Julia 函式陣列。
建立陣列的方法有很多:您可以建立空的、未初始化的、完整的、基於序列的、稀疏的、密集的等等。這取決於手頭的任務。
您可以使用 Array{type}(dims) 指定陣列的型別和維度(注意是大寫“A”),將型別放在大括號中,並將維度放在括號中。undef 表示陣列尚未初始化為已知值。
julia> array = Array{Int64}(undef, 5)
5-element Array{Int64,1}:
4520632328
4614616448
4520668544
4520632328
4615451376
julia> array3 = Array{Int64}(undef, 2, 2, 2)
2×2×2 Array{Int64,3}:
[:, :, 1] =
4452254272 4452255728
4452256400 4456808080
[:, :, 2] =
4456808816 4452255728
4456808816 4452254272
隨機數提醒您,您建立了一個未初始化的陣列,但沒有填充任何有意義的資訊。
可以建立包含不同型別元素的陣列
julia> [1, "2", 3.0, sin, pi]
5-element Array{Any, 1}:
1
"2"
3.0
sin
π = 3.1415926535897...
這裡,陣列有五個元素,但它們是奇怪的混合:數字、字串、函式、常量——因此 Julia 建立了一個 Any 型別的陣列
julia> typeof(ans)
Array{Any,1}
要建立特定型別的陣列,您也可以使用型別定義和方括號
julia> Int64[1, 2, 3, 4]
4-element Array{Int64,1}:
1
2
3
4
如果您認為可以在宣告型別化陣列時偷偷潛入一個錯誤型別的 value,那麼您將被發現
julia> Int64[1, 2, 3, 4, 5, 6, 7, 8, 9, 10.1] ERROR: InexactError()
您也可以用這種方式建立空陣列
julia> b = Int64[]
0-element Array{Int64,1}
julia> b = String[]
0-element Array{String,1}
julia> b = Float64[]
0-element Array{Float64,1}
如果在定義陣列時省略逗號,您可以快速建立二維陣列。這是一個單行多列陣列
julia> [1 2 3 4]
1x4 Array{Int64,2}:
1 2 3 4
請注意響應第一行中的 1x4 {...,2}。
您可以使用分號新增另一行
julia> [1 2 3 4 ; 5 6 7 8]
2x4 Array{Int64,2}:
1 2 3 4
5 6 7 8
比較這兩個:[1,2,3,4,5] 和 [1 2 3 4 5]。
使用逗號,此陣列可以稱為“列向量”,有 5 行 1 列
julia> [1, 2, 3, 4, 5]
5-element Array{Int64,1}:
1
2
3
4
5
但使用空格,此陣列可以稱為“行向量”,有 1 行 5 列
julia> [1 2 3 4 5]
1x5 Array{Int64,2}:
1 2 3 4 5
- 請注意這裡的 {Int64,2},它告訴您這是一個 Int64 的二維陣列(有 1 行 5 列)。在這兩種情況下,它們都是標準的 Julia 陣列。
這樣建立的陣列可以用作矩陣
julia> [1 2 3; 4 5 6]
2x3 Array{Int64,2}:
1 2 3
4 5 6
當然,您可以建立 3 維或更多維的陣列/矩陣。
有許多函式可以讓您一次建立並填充陣列。請參閱 建立和填充陣列。
請注意 Julia 如何區分 Array{Float64,1} 和 Array{Float64,2}
julia> x = rand(5)
5-element Array{Float64,1}:
0.4821773161183929
0.5811789456966778
0.7852806713801641
0.23626682918327369
0.6777187748570226
julia> x = rand(5, 1)
5×1 Array{Float64,2}:
0.0723474801859294
0.6314375868614579
0.21065681560040828
0.8300724654838343
0.42988769728089804
Julia 提供了 Vector 和 Matrix 建構函式,但它們只是未初始化一維和二維陣列的別名
julia> Vector(undef, 5)
5-element Array{Any,1}:
#undef
#undef
#undef
#undef
#undef
julia> Matrix(undef, 5, 5)
5x5 Array{Any,2}:
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
在 Julia 中,冒號 (:) 有多種用途。其中一個用途是定義數字的範圍和序列。你可以直接輸入來建立一個範圍物件
julia> 1:10 1:10
這種形式可能看起來不太有用,但它為 Julia 中任何需要數字範圍或序列的任務提供了原材料。
你可以在迴圈表示式中使用它
julia> for n in 1:10 print(n) end 12345678910
或者你可以使用 collect() 來構建一個包含這些數字的陣列
julia> collect(1:10)
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
你不必從整數開始和結束
julia> collect(3.5:9.5)
7-element Array{Float64,1}:
3.5
4.5
5.5
6.5
7.5
8.5
9.5
還有一個三部分版本的範圍物件,start:step:stop,它允許你指定一個不為 1 的步長。例如,這會構建一個元素從 0 到 100 以 10 為步長遞增的陣列
julia> collect(0:10:100)
11-element Array{Int64,1}:
0
10
20
30
40
50
60
70
80
90
100
要向下而不是向上,你必須使用負的步長值
julia> collect(4:-1:1)
4-element Array{Int64,1}:
4
3
2
1
除了使用 collect() 從範圍中建立陣列之外,你還可以使用省略號 (...) 運算子(三個點)放在最後一個元素之後
julia> [1:6...]
6-element Array{Int64,1}:
1
2
3
4
5
6
(... 省略號有時被稱為splat 運算子。它表示一系列引數。)
但是,collect() 更快,也是將範圍轉換為陣列的推薦方法。但是,你可以在 Julia 的許多情況下使用範圍物件,並且並不總是需要將它們擴充套件為陣列。
另一個有用的函式是 range(),它構造一個範圍物件,該物件從一個起始值到一個結束值,以特定的步長大小執行特定數量的步長。你不需要計算所有資訊,因為 Julia 會透過組合 step、length 和 stop 關鍵字的值來為你計算缺失的部分。例如,要以 12 步長從 1 到 100
julia> range(1, length=12, stop=100) 1.0:9.0:100.0
或者以 10 步長從 1 開始,停止在 100 或之前
julia> range(1, stop=100, step=10) 1:10:91
如果你真的想要以陣列形式,你可以使用範圍物件來構建陣列
julia> collect(range(1, length=12, stop=100))
12-element Array{Float64,1}:
1.0
10.0
19.0
28.0
37.0
46.0
55.0
64.0
73.0
82.0
91.0
100.0
請注意,它為你提供了一個 Float64 陣列,而不是一個 Integer 陣列,即使這些值可以是整數。
對於對數範圍(有時稱為“對數空間”),你可以使用簡單的範圍物件,然後將 exp10 函式 (10^x) 廣播到範圍的每個元素。
julia> exp10.(range(2.0, stop=3.0, length=5))
5-element Array{Float64,1}:
100.0
177.82794100389228
316.22776601683796
562.341325190349
1000.0
請參閱廣播和點語法。
對範圍物件使用 step() 可以找到步長大小
julia> step(range(1, length=10, stop=100)) 11.0
如果你知道開始和步長,但不知道結束,並且知道想要多少個元素,請使用 range()
julia> range(1, step=3, length=20) |> collect
20-element Array{Int64,1}:
1
4
7
10
13
16
19
22
25
28
31
34
37
40
43
46
49
52
55
58
如你所見,如果你不在 for 迴圈中使用範圍物件,如果你願意,可以使用 collect() 直接從範圍物件中獲取所有值
julia> collect(0:5:100)
21-element Array{Int64,1}:
0
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
但是,你並不總是需要在處理範圍之前將它們轉換為陣列——你通常可以直接迭代它們。例如,你不需要寫這個
for i in collect(1:6)
println(i)
end
1 2 3 4 5 6
因為它工作得一樣好(而且可能更快),如果你省略 collect()
for i in 1:6
println(i)
end
1 2 3 4 5 6
一種建立陣列的實用方法,其中每個元素都可以使用一個小計算來生成,是使用推導(在推導中描述)。
例如,要建立一個包含 5 個數字的陣列
julia> [n^2 for n in 1:5]
5-element Array{Int64,1}:
1
4
9
16
25
使用兩個迭代器,你可以輕鬆地建立一個二維陣列或矩陣
julia> [r * c for r in 1:5, c in 1:5]
5x5 Array{Int64,2}:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
你可以在末尾新增一個 if 測試來過濾(保留)透過測試的值
julia> [i^2 for i=1:10 if i != 5]
9-element Array{Int64,1}:
1
4
9
16
36
49
64
81
100
生成器表示式類似,並且可以用類似的方式使用
julia> collect(x^2 for x in 1:10)
10-element Array{Int64,1}:
1
4
9
16
25
36
49
64
81
100
julia> collect(x^2 for x in 1:10 if x != 1)
9-element Array{Int64,1}:
4
9
16
25
36
49
64
81
100
生成器表示式的優勢在於它們在需要時生成值,而不是首先構建一個數組來儲存它們。
有許多函式允許你建立具有特定內容的陣列。當你在二維陣列中使用矩陣時,這些函式非常有用
- zeros(m, n) 建立一個具有 m 行和 n 列的零陣列/矩陣
julia> zeros(2, 3)
2x3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
如果你需要,可以指定零的型別
julia> zeros(Int64, 3, 5)
3×5 Array{Int64,2}:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
- ones(m, n) 建立一個具有 m 行和 n 列的單位陣列/矩陣
julia> ones(2, 3)
2x3 Array{Float64,2}:
1.0 1.0 1.0
1.0 1.0 1.0
- rand(m, n) 建立一個包含隨機數字的 m 行 n 列矩陣
julia> rand(2, 3)
2×3 Array{Float64,2}:
0.488552 0.657078 0.895564
0.0190633 0.0120305 0.772106
- rand(range, m, n) 建立一個包含給定範圍內的數字的矩陣
julia> rand(1:6, 3, 3)
3x3 Array{Int64,2}:
4 4 1
3 2 3
6 3 3
- randn(m, n) 建立一個包含均值為 0、標準差為 1 的正態分佈隨機數字的 m 行 n 列矩陣。
除了 zeros()、ones() 函式之外,還有 trues()、falses()、fill() 和 fill!() 函式。
trues() 和 falses() 函式用布林值真或假填充陣列
julia> trues(3, 4)
3x4 BitArray{2}:
true true true true
true true true true
true true true true
請注意結果是一個 BitArray。
你可以使用 fill() 來建立一個具有特定值的陣列,即一個包含重複副本的陣列
julia> fill(42, 9)
9-element Array{Int64,1}:
42
42
42
42
42
42
42
42
42
julia> fill("hi", 2, 2)
2x2 Array{String,2}:
"hi" "hi"
"hi" "hi"
對於 fill!(),感嘆號 (!) 或“bang”是為了警告你,你將要更改現有陣列的內容(一個有用的指示,在整個 Julia 中都被採用)。
julia> a = zeros(10)
10-element Array{Float64,1}:
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
julia> fill!(a, 42)
10-element Array{Float64,1}:
42.0
42.0
42.0
42.0
42.0
42.0
42.0
42.0
42.0
42.0
讓我們將一個假陣列更改為真陣列
julia> trueArray = falses(3,3)
3x3 BitArray{2}:
false false false
false false false
false false false
julia> fill!(trueArray, true)
3x3 BitArray{2}:
true true true
true true true
true true true
julia> trueArray
3x3 BitArray{2}:
true true true
true true true
true true true
你可以使用 range() 函式來建立向量式陣列,然後使用 reshape() 將它們更改為二維陣列
julia> a = reshape(range(0, stop=100, length=30), 10, 3)
10×3 reshape(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, 10, 3) with eltype Float64:
0.0 34.4828 68.9655
3.44828 37.931 72.4138
6.89655 41.3793 75.8621
10.3448 44.8276 79.3103
13.7931 48.2759 82.7586
17.2414 51.7241 86.2069
20.6897 55.1724 89.6552
24.1379 58.6207 93.1034
27.5862 62.069 96.5517
31.0345 65.5172 100.0
結果是一個 10 行 3 列的陣列,包含 0 到 100 之間均勻間隔的數字。
一個透過重複較小的陣列來建立陣列的有用函式是 repeat()。
它的語法的第一個選項是 repeat(A, n, m),源陣列在第一個維度(行)中重複 n 次,在第二個維度(列)中重複 m 次。
你不必提供第二個維度,只需提供想要多少行
julia> repeat([1, 2, 3], 2)
6-element Array{Int64,1}:
1
2
3
1
2
3
julia> repeat([1 2 3], 2)
2x3 Array{Int64,2}:
1 2 3
1 2 3
第二個選項指定了額外的列
julia> repeat([1, 2, 3], 2, 3)
6x3 Array{Int64,2}:
1 1 1
2 2 2
3 3 3
1 1 1
2 2 2
3 3 3
julia> repeat([1 2 3], 2, 3)
2x9 Array{Int64,2}:
1 2 3 1 2 3 1 2 3
1 2 3 1 2 3 1 2 3
repeat() 函式還允許你透過複製源陣列的行和列來建立陣列。inner 和 outer 選項確定是否重複行和/或列。例如,inner = [2, 3] 建立一個數組,其中每行有兩份副本,每列有三份副本
julia> repeat([1, 2], inner = [2, 3])
4x3 Array{Int64,2}:
1 1 1
1 1 1
2 2 2
2 2 2
相比之下,這是 outer = [2,3]
julia> repeat([1, 2], outer = [2, 3])
4x3 Array{Int64,2}:
1 1 1
2 2 2
1 1 1
2 2 2
請注意,後者等效於 repeat([1, 2], 2, 3)。outer 關鍵字更具意義的示例是當它與 inner 結合使用時。這裡,初始矩陣中每行的每個元素都按行重複,然後,結果矩陣中的每個行切片都按列重複三次
julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
4×6 Array{Int64,2}:
1 2 1 2 1 2
1 2 1 2 1 2
3 4 3 4 3 4
3 4 3 4 3 4
我們之前看到的 Array() 函式為你構建特定型別的陣列
julia> Array{Int64}(undef, 6)
6-element Array{Int64,1}:
4454517776
4454517808
4454517840
4454517872
4454943824
4455998977
這是未初始化的;看起來奇怪的數字只是分配給儲存新陣列的記憶體之前的內容。
建立陣列的陣列很容易。有時你想要指定原始內容
julia> a = Array[[1, 2], [3,4]]
2-element Array{Array,1}:
[1, 2]
[3, 4]
Array建構函式也可以構造一個數組的陣列
julia> Array[1:3, 4:6]
2-element Array{Array,1}:
[1,2,3]
[4,5,6]
使用 reshape() 函式,你當然可以只建立一個簡單陣列,然後改變其形狀
julia> reshape([1, 2, 3, 4, 5, 6, 7, 8], 2, 4)
2x4 Array{Int64,2}:
1 3 5 7
2 4 6 8
相同的技術可以用來建立三維陣列。這裡是一個字串的三維陣列
julia> Array{String}(undef, 2, 3, 4)
2x3x4 Array{String,3}:
[:, :, 1] =
#undef #undef #undef
#undef #undef #undef
[:, :, 2] = #undef #undef #undef #undef #undef #undef
[:, :, 3] = #undef #undef #undef #undef #undef #undef
[:, :, 4] = #undef #undef #undef #undef #undef #undef
每個元素都設定為“未定義”——#undef。
push!() 函式將另一個專案推送到陣列的末尾
julia> push!(a, rand(1:100, 5))
3-element Array{Array,1}:
[1, 2]
[3, 4]
[4, 71, 82, 60, 48]
julia> push!(a, rand(1:100, 5))
4-element Array{Array,1}:
[1,2]
[3,4]
[4, 71, 82, 60, 48]
[4, 22, 52, 5, 14]
或者你可能想要建立空的陣列
julia> a = Array{Int}[]
0-element Array{Array{Int64,N} where N,1}
julia> push!(a, [1, 2, 3])
1-element Array{Array{Int64,N} where N,1}:
[1, 2, 3]
julia> push!(a, [4, 5, 6])
2-element Array{Array{Int64,N} where N,1}:
[1, 2, 3]
[4, 5, 6]
您可以使用Vector作為Array的別名。
julia> a = Vector{Int}[[1, 2], [3, 4]]
2-element Array{Array{Int64,1},1}:
[1, 2]
[3, 4]
julia> push!(a, rand(1:100, 5))
3-element Array{Array{Int64, 1},1}:
[1, 2]
[3, 4]
[12, 65, 53, 1, 82]
julia> a[2]
2-element Array{Int64,1}:
3
4
julia> a[2][1]
3
複製陣列
[edit | edit source]如果您已有陣列,並希望建立另一個具有相同維度的陣列,可以使用similar()函式。
julia> a = collect(1:10); # hide the output with the semicolon
julia> b = similar(a)
10-element Array{Int64,1}:
4482975872
4482975792
1
4482975952
4482976032
4482976112
3
3
2
4520636161
請注意,陣列的維度被複制了,但值沒有被複制,而是從記憶體中的隨機位複製而來。不過,您可以更改型別和維度,因此它們不必那麼相似。
julia> c = similar(b, String, (2, 2))
2x2 Array{String,2}:
#undef #undef
#undef #undef
無論如何,都有一個copy()函式。
矩陣運算:將陣列用作矩陣
[edit | edit source]在 Julia 中,二維陣列可以作為矩陣使用。所有用於處理陣列的函式都可以使用(如果維度和內容允許)作為矩陣。
鍵入矩陣的快捷方式是使用空格分隔元素(形成行),並使用分號分隔行。所以
julia> [1 0 ; 0 1]
2x2 Array{Int64,2}:
1 0
0 1
|
|
你也可以這樣做
julia> id = reshape([1, 2, 3, 4], 2, 2)
2×2 Array{Int64,2}:
1 3
2 4
它接受一個標準陣列,並將其重新整形為兩行兩列。請注意,矩陣是按列填充的。
如果您不使用逗號或分號
julia> [1 2 3 4]
您將建立一個單行陣列/矩陣
1x4 Array{Int64,2}:
1 2 3 4
在每種情況下,請注意型別值後面括號({Int64,2})中的 2。這表示一個二維陣列。
您可以透過將兩個陣列並排放置來建立一個數組陣列,如下所示
julia> [[1, 2, 3], [4, 5, 6]]
2-element Array{Array{Int64,1},1}:
[1, 2, 3]
[4, 5, 6]
當您省略逗號時,您將把列並排放置,您將得到以下結果
julia> [[1, 2, 3] [4, 5, 6]]
3×2 Array{Int64,2}:
1 4
2 5
3 6
訪問陣列的內容
[edit | edit source]要訪問陣列或矩陣的元素,請在陣列名稱後面用方括號加上元素編號。這是一個一維陣列
julia> a = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
這是第五個元素
julia> a[5] 50
第一個元素的索引編號為 1。Julia 是從 1 開始對列表和陣列中的元素進行索引的語言之一,而不是從 0 開始。(因此它與 Matlab、Mathematica、Fortran、Lua 和 Smalltalk 等精英公司在一起,而大多數其他程式語言則堅定地站在 0 為基準的索引器陣營中。)
最後一個元素被稱為end(不是 -1,像在其他一些語言中那樣)
julia> a[end] 100
類似地,您可以使用以下方法訪問倒數第二個元素
julia> a[end-1] 90
(對倒數第三個元素等採用類似的語法)。
您可以提供一組索引編號,在每端用一對括號括起來
julia> a[[3,6,2]]
3-element Array{Int64,1}:
30
60
20
或者提供一個索引編號範圍
julia> a[2:2:end]
5-element Array{Int64,1}:
20
40
60
80
100
您甚至可以使用true和false值來選擇元素
julia> a[[true, true, false, true, true, true, false, true, false, false]]
6-element Array{Int64,1}:
10
20
40
50
60
80
這是一個二維陣列,行用分號分隔
julia> a2 = [1 2 3; 4 5 6; 7 8 9]
3x3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
julia> a2[1]
1
如果您只要求一個二維陣列的元素,您將收到它,就像陣列被按列展開一樣,即先向下,然後橫向。在這種情況下,您將得到 4,而不是 2
julia> a2[2] 4
請求行和列按預期工作
julia> a2[1, 2] 2
這是第 1 行,第 2 列。這是第 1 行,第 3 列
julia> a2[1, 3] 3
但不要將行/列索引弄反
julia> a2[1, 4]
ERROR: BoundsError: attempt to access 3×3 Array{Int64,2} at index [1, 4]
Stacktrace:
[1] getindex(::Array{Int64,2}, ::Int64, ::Int64) at ./array.jl:498
順便說一句,有一種從陣列中獲取元素的替代方法:getindex()函式
julia> getindex(a2, 1, 3)
3
julia> getindex(a2, 1, 4)
ERROR: BoundsError: attempt to access 3×3 Array{Int64,2} at index [1, 4]
Stacktrace:
[1] getindex(::Array{Int64,2}, ::Int64, ::Int64) at ./array.jl:498
使用冒號表示所有行或列。例如,這是“所有行,第二列”
julia> a2[:, 2]
3-element Array{Int64,1}:
2
5
8
這是“第二行,所有列”
julia> a2[2, :]
3-element Array{Int64,1}:
4
5
6
逐元素和向量化運算
[edit | edit source]許多 Julia 函式和運算子專門設計用於處理陣列。這意味著您不必總是遍歷陣列並單獨處理每個元素。
一個簡單的例子是基本算術運算子的使用。如果另一個引數是單個值,則這些運算子可以直接用於陣列
julia> a = collect(1:10);
julia> a * 2
10-element Array{Int64,1}:
2
4
6
8
10
12
14
16
18
20
並且新陣列的每個元素都是原始陣列的 2 倍。同樣
julia> a / 100
10-element Array{Float64,1}:
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
並且新陣列的每個元素都是原始陣列的 100 分之一。
這些操作被稱為逐元素操作。
許多運算子可以在前面加上一個點 (.)。這些版本與其非點版本相同,並在陣列上逐元素工作。例如,乘法函式 (*) 可以逐元素使用,使用.*。這使您可以逐元素將陣列或範圍相乘
julia> n1 = 1:6;
julia> n2 = 100:100:600;
julia> n1 .* n2
6-element Array{Int64,1}:
100
400
900
1600
2500
3600
並且結果的第一個元素是兩個陣列的第一個元素相乘的結果,依此類推。
除了算術運算子之外,一些比較運算子也有逐元素版本。例如,與其在迴圈中使用==比較兩個陣列,不如使用.==。這裡有兩個十個數的陣列,一個是連續的,另一個是無序的,以及一個逐元素比較,以檢視陣列b中有多少元素恰好在與陣列a相同的位置。
julia> a = 1:10; b=rand(1:10, 10); a .== b
10-element BitArray{1}:
true
false
true
false
false
false
false
false
false
false
廣播:用於向量化函式的點語法
[edit | edit source]這種使用點語法將函式逐元素應用於陣列的技術稱為廣播。在函式名稱後面加上一個點/句號,然後是左括號,並將陣列或範圍作為引數提供。例如,這裡有一個簡單的函式,它將兩個數字相乘
julia> f(a, b) = a * b f (generic function with 1 method)
它在兩個標量上按預期工作
julia> f(2, 3) 6
但很容易將此函式應用於陣列。只需使用點語法
julia> f.([1, 4, 2, 8, 7], 10)
5-element Array{Int64,1}:
10
40
20
80
70
julia> f.(100, 1:10)
10-element Array{Int64,1}:
100
200
300
400
500
600
700
800
900
1000
在第一個示例中,Julia 自動將第二個引數視為陣列,以便乘法能夠正確地工作。
在組合範圍和向量化函式時要注意這一點
julia> 0:10 .* 0.5 |> collect
6-element Array{Float64,1}:
0.0
1.0
2.0
3.0
4.0
5.0
julia> 0.5 .* 0:10 |> collect
11-element Array{Float64,1}:
0.0
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
10.0
第一個示例等效於0:(10 .* 0.5),您可能想要(0:10) .* 0.5。
min() 和 max()
[edit | edit source]注意max()和min()。您可能會認為max()可以用於陣列,例如這樣,以找到最大元素
julia> r = rand(0:10, 10)
10-element Array{Int64,1}:
3
8
4
3
2
5
7
3
10
10
但不是…
julia> max(r)
LoadError: MethodError: no method matching max(::Array{Int64,1})
...
max函式返回其引數中的最大值。要查詢陣列中的最大元素,可以使用相關的函式maximum()
julia> maximum(r) 10
您可以對兩個或多個數組使用max()來進行逐元素檢查,返回另一個包含最大值的陣列
julia> r = rand(0:10, 10); s = rand(0:10, 10); t = rand(0:10,10);
julia> max(r, s, t)
10-element Array{Int64,1}:
8
9
7
5
8
9
6
10
9
9
min()和minimum()的行為類似。
使max在陣列上起作用的方法是使用省略號(splat)運算子
julia> max(r...) 9
您可以測試陣列中的每個值並在單個操作中更改它,使用逐元素運算子。這裡有一個從 0 到 10 的隨機整數陣列
julia> a = rand(0:10,10, 10)
10x10 Array{Int64,2}:
10 5 3 4 7 9 5 8 10 2
6 10 3 4 6 1 2 2 5 10
7 0 3 4 1 10 7 7 0 2
4 9 5 2 4 2 1 6 1 9
0 0 6 4 1 4 8 10 1 4
10 4 0 5 1 0 4 4 9 2
9 4 10 9 6 9 4 5 1 1
1 9 10 10 1 9 3 2 3 10
4 6 3 2 7 7 5 4 6 8
3 8 0 7 1 0 1 9 7 5
現在您可以測試每個值是否等於 0,然後將這些元素設定為 11,如下所示
julia> a[a .== 0] .= 11;
julia> a
10x10 Array{Int64,2}:
10 5 3 4 7 9 5 8 10 2
6 10 3 4 6 1 2 2 5 10
7 11 3 4 1 10 7 7 11 2
4 9 5 2 4 2 1 6 1 9
11 11 6 4 1 4 8 10 1 4
10 4 11 5 1 11 4 4 9 2
9 4 10 9 6 9 4 5 1 1
1 9 10 10 1 9 3 2 3 10
4 6 3 2 7 7 5 4 6 8
3 8 11 7 1 11 1 9 7 5
這是因為a .== 0返回一個包含true和false值的陣列,然後使用這些值選擇要設定為 11 的a元素。
如果您正在對二維矩陣進行算術運算,您可能需要閱讀有關矩陣算術的更多資訊:矩陣算術
行和列
[edit | edit source]對於二維陣列,您可以使用括號、冒號和逗號來提取單個行和列或行和列的範圍。
使用此表
julia> table = [r * c for r in 1:5, c in 1:5]
5x5 Array{Int64,2}:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
您可以使用以下方法找到單行(注意逗號)
julia> table[1, :]
1x5 Array{Int64,2}:
5-element Array{Int64,1}:
1
2
3
4
5
您可以使用範圍後跟逗號和冒號來獲取一系列行
julia> table[2:3,:]
2x5 Array{Int64,2}:
2 4 6 8 10
3 6 9 12 15
要選擇列,請從冒號後跟逗號開始
julia> table[:, 2]
5-element Array{Int64,1}:
2
4
6
8
10
單獨使用冒號訪問整個陣列
julia> table[:]
25-element Array{Int64,1}:
1
2
3
4
5
2
4
6
8
10
3
6
9
12
15
4
8
12
16
20
5
10
15
20
25
要提取一系列列
julia> table[:, 2:3]
5x2 Array{Int64,2}:
2 3
4 6
6 9
8 12
10 15
在陣列中查詢專案
[edit | edit source]如果您想知道陣列是否包含一個專案,請使用in()函式,該函式可以透過兩種方式呼叫
julia> a = 1:10
julia> 3 in a true
或者以函式呼叫的形式
julia> in(3, a) # needle ... haystack true
有一組以find開頭的函式——例如findall()、findfirst()、findnext()、findprev()和findlast()——您可以使用這些函式來獲取與特定值匹配或透過測試的陣列單元的索引或索引。它們中的每一個都有兩種或多種形式。
這裡有一個小素數陣列
julia> smallprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];
要查詢數字的第一個出現,並獲得其索引,您可以使用findfirst()函式的以下方法
julia> findfirst(isequal(13), smallprimes) 6
因此陣列中 13 的第一個出現位於第六個單元格中
julia> smallprimes[6] 13
此函式類似於 Julia 中的許多函式,它接受函式作為第一個引數。該函式應用於陣列的每個元素,如果函式返回 true,則返回該元素或其索引。此函式返回第一個元素的索引。
這裡還有另一個使用匿名函式的示例
julia> findfirst(x -> x == 13, smallprimes) 6
findall()函式返回一個索引陣列,指向函式應用時返回 true 的每個元素
julia> findall(isinteger, smallprimes)
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
julia> findall(iseven, smallprimes)
1-element Array{Int64,1}:
1
請記住,這些是索引編號的陣列,而不是實際的單元格值。可以使用這些索引來提取相應的 value,使用標準的方括號語法
julia> smallprimes[findall(isodd, smallprimes)]
9-element Array{Int64,1}:
3
5
7
11
13
17
19
23
29
而 findfirst() 返回單個數字 - 匹配的第一個單元格的索引
julia> findfirst(iseven, smallprimes) 1
julia> smallprimes[findfirst(iseven, smallprimes)] 2
findnext() 函式與 findall() 和 findfirst() 函式非常相似,但接受一個額外的數字,告訴函式從陣列中間的某個位置開始搜尋,而不是從開頭開始搜尋。例如,如果 findfirst(smallprimes,13) 找到陣列中數字 13 首次出現的索引,我們可以使用此值在 findnext() 中繼續搜尋。
julia> findnext(isodd, smallprimes, 1 + findfirst(isequal(13), smallprimes)) 7
julia> smallprimes[ans] 17
要返回陣列 B 中元素的索引,其中陣列 A 的元素可以找到,請使用 findall(in(A), B)
julia> findall(in([11, 5]), smallprimes)
2-element Array{Int64,1}:
3
5
julia> smallprimes[3]
5
julia> smallprimes[5]
11
應注意返回索引的順序。
使用我們的二維陣列
julia> a2 = [1 2 3; 4 5 6; 7 8 9]
3x3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
我們可以使用以下函數了解更多資訊
ndims()size()length()count()
ndims() 返回維數,即向量為 1,表格為 2,依此類推
julia> ndims(a2) 2
size() 以元組的形式返回陣列的行數和列數
julia> size(a2) (3,3)
length() 告訴你陣列包含多少個元素
julia> length(a2) 9
你可以使用 count() 來找出某個特定值出現了多少次。例如,有多少個非零項?
julia> count(!iszero, a2) 9
要查詢陣列/矩陣的逆矩陣、行列式和其他方面,請參見 操作矩陣。
要將索引號(1 到 n)和行/列號(1:r,1:c)相互轉換,可以使用
julia> CartesianIndices(a2)[6] CartesianIndex(3, 2)
例如,要查詢第六個元素的行和列。
要反過來操作,第 3 行第 2 列對應哪個索引號?使用笛卡爾索引的相反形式,線性索引
julia> LinearIndices(a2)[3, 2] 6
diff() 用於查詢陣列中每個元素之間的差值
julia> [2x for x in 1:10]
10-element Array{Int64,1}:
2
4
6
8
10
12
14
16
18
20
julia> [2x for x in 1:10] |> diff
9-element Array{Int64,1}:
2
2
2
2
2
2
2
2
2
union() 建立一個新的陣列,它是兩個或多個數組的並集或組合。該操作將刪除重複項,結果包含每個元素的單個版本
julia> odds = collect(1:2:10)
5-element Array{Int64,1}:
1
3
5
7
9
julia> evens = collect(2:2:10)
5-element Array{Int64,1}:
2
4
6
8
10
julia> union(odds, evens)
10-element Array{Int64,1}:
1
3
5
7
9
2
4
6
8
10
注意,新的並集的排序反映了原始排序。此示例根本沒有對數字進行排序
julia> union(1:5, 1:10, 5:-1:-5)
16-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
0
-1
-2
-3
-4
-5
intersect() 返回一個新的陣列,它是兩個或多個數組的交集。結果包含每個元素的一個例項,但前提是它在每個陣列中都出現過
julia> intersect(1:10, 5:15) 5:10
julia> intersect(5:20, 1:15, 3:12) 5:12
setdiff() 查詢兩個陣列之間的差異,即第一個陣列中存在而第二個陣列中不存在的元素
julia> setdiff(1:15, 5:20)
4-element Array{Int64,1}:
1
2
3
4
julia> setdiff(5:20, 1:15)
5-element Array{Int64,1}:
16
17
18
19
20
有一組相關的函式,允許你對陣列的元素進行操作。
filter() 查詢並保留透過測試的元素。在這裡,我們使用 isodd() 函式(將其作為命名函式傳遞,不帶括號,而不是帶括號的函式呼叫)來過濾(保留)陣列中所有奇數元素。
julia> filter(isodd, 1:10)
5-element Array{Int64,1}:
1
3
5
7
9
與許多 Julia 函式一樣,還有一個版本會更改陣列。因此,filter() 返回原始陣列的副本,而 filter!() 會更改陣列。
我們之前遇到的 count() 函式類似於 filter(),但只是計算滿足條件的元素數量
julia> count(isodd, 1:100) 50
此外,any() 函式只是告訴你是否有任何元素滿足條件
julia> any(isodd, 1:100) true
而 all() 函式告訴你所有元素是否都滿足條件。在這裡,all() 檢查 filter() 是否正常工作。
julia> all(isodd, filter(isodd, 1:100)) true
要從陣列中選擇一個隨機元素
julia> a = collect(1:100); julia> a[rand(1:end)] 14
因為陣列是 Julia 的基礎,所以這裡無法描述數十個陣列處理函式。但這裡有一些選擇
查詢陣列的極值
julia> a = rand(100:110, 10)
10-element Array{Int64,1}:
109
102
104
108
103
110
100
108
101
101
julia> extrema(a) (100,110)
findmax() 找到最大元素並將其和索引以元組形式返回
julia> findmax(a) (110,6)
使用 argmax() 僅返回索引。
maximum() 和 minimum() 函式允許你提供函式來確定如何確定“最大值”。如果你陣列不是簡單的向量,這將非常有用。此示例查詢最大陣列元素,其中“最大”是指“具有最大最後值”
julia> maximum(x -> last(x), [(1, 2), (2, 23), (8, 12), (7, 2)]) 23
sum()、prod()、mean()、middle() 等函式按你期望的那樣工作
(mean() 和 middle() 已移至標準庫中的 Statistics 模組中;你可能需要先輸入“using Statistics”才能使用它們)
julia> sum(a) 1046
julia> prod(1:10) 3628800
julia> mean(a) 104.6
julia> middle(a) 105.0
sum()、mean() 和 prod() 也允許你提供函式:該函式應用於每個元素,然後對結果進行求和/求平均值/求積
julia> sum(sqrt, 1:10) # the sum of the square roots of the first 10 integers 22.4682781862041 julia> mean(sqrt, 1:10) # the mean of the square roots of the first 10 integers 2.24682781862041
Combinatorics.jl 包中有一些函式,可以讓你查詢陣列的組合和排列。combinations() 查詢陣列中元素的所有可能組合:你可以指定每個組合中的元素數量
julia> ]
(v1.0) pkg> add Combinatorics # (do this just once)
julia> using Combinatorics
julia> collect(combinations(a, 3))
120-element Array{Array{Int64,1},1}:
[109,102,104]
[109,102,108]
[109,102,103]
[109,102,110]
[109,102,100]
[109,102,108]
[109,102,101]
[109,102,101]
[109,104,108]
[109,104,103]
[109,104,110]
[109,104,100]
[109,104,108]
⋮
[103,108,101]
[103,101,101]
[110,100,108]
[110,100,101]
[110,100,101]
[110,108,101]
[110,108,101]
[110,101,101]
[100,108,101]
[100,108,101]
[100,101,101]
[108,101,101]
而 permutations() 生成所有排列。有很多排列 - 在實踐中,你可能不需要使用 collect() 將專案收集到陣列中
julia> length(permutations(a)) 3628800
要將專案新增到陣列末尾,請使用 push!()
julia> a = collect(1:10); push!(a, 20)
11-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
20
像往常一樣,感嘆號提醒你此函式會更改陣列。你只能向向量末尾新增專案。
要將專案新增到開頭,請使用 pushfirst!()
julia> pushfirst!(a, 0)
12-element Array{Int64,1}:
0
1
2
3
4
5
6
7
8
9
10
20
要將元素插入陣列中的給定索引處,請使用 splice!() 函式。例如,這是一個數字列表,其中明顯缺少一個數字
julia> a = [1, 2, 3, 5, 6, 7, 8, 9]
8-element Array{Int64,1}:
1
2
3
5
6
7
8
9
使用 splice!() 在特定索引值範圍內插入序列。Julia 返回被替換的值。陣列會變大以容納新元素,插入序列之後的元素將被向下推。讓我們在位置 4:5 插入數字範圍 4:6
julia> splice!(a, 4:5, 4:6)
2-element Array{Int64,1}:
5
6
你可能會想檢查新值是否已正確插入
julia> a
9-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
現在,如果你想在特定索引間位置插入一些值,你將不得不使用稱為空範圍的功能。在這種情況下,索引 n-1 和 n 之間的間隙表示為 n:n-1。
例如
julia> L = ['a','b','f']
3-element Array{Char,1}:
'a'
'b'
'f'
julia> splice!(L, 3:2, ['c','d','e'])
0-element Array{Char,1}
julia> L
6-element Array{Char,1}:
'a'
'b'
'c'
'd'
'e'
'f'
如果你不提供替換,也可以使用 splice!() 刪除元素並移動其餘元素。
julia> a = collect(1:10);
julia> splice!(a,5);
julia> a
9-element Array{Int64,1}:
1
2
3
4
6
7
8
9
10
要刪除最後一個專案
julia> pop!(a) 10
以及第一個專案
julia> popfirst!(a) 1
可以使用 deleteat!() 和 splice!() 等函式對陣列(以及類似的資料結構)進行更激進的修改。你可以透過多種方式找出元素的索引。一旦你知道了索引,就可以使用 deleteat!() 刪除元素,方法是提供其索引號
julia> a = collect(1:10);
julia> findfirst(isequal(6), a) 6
julia> deleteat!(a, findfirst(isequal(6), a))
9-element Array{Int64,1}:
1
2
3
4
5
7
8
9
10
deleteat!() 也接受一個範圍或迭代器來指定索引,因此你可以這樣做
julia> deleteat!(a, 2:6)
4-element Array{Int64,1}:
1
8
9
10
請記住,你始終可以使用過濾器刪除一組元素:請參見 過濾。
如果你想對陣列做一些操作,可能會有一個函式可以做到,而且有時會帶有一個感嘆號來提醒你潛在的後果。以下是一些其他此類陣列修改函式
resize!()更改向量的長度append!()將第二個集合推送到第一個集合的後面prepend!()在第一個向量的開頭插入元素empty!(a)刪除所有元素unique(a)從陣列“a”中刪除重複元素,但不覆蓋陣列。unique!(a)從陣列“a”中刪除重複元素,並覆蓋陣列。rotr90(a)複製一個數組,並將其順時針旋轉 90 度
julia> rotr90([1 2 3 ; 4 5 6])
3x2 Array{Int64,2}:
4 1
5 2
6 3
circshift(a)將元素“迴圈”移動一定步數
julia> circshift(1:6, 1)
6-element Array{Int64,1}:
6
1
2
3
4
5
此函式也可以對二維陣列進行迴圈移位。例如,這是一個表格
julia> table = collect(r*c for r in 1:5, c in 1:5)
5×5 Array{Int64,2}:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
透過提供一個元組,你可以移動行和列。例如:將列移動 0 步,將行移動 1 步,會將第一維移動 0 步,第二維移動 1 步。第一維向下,第二維向右
julia> circshift(table, (0, 1))
5×5 Array{Int64,2}:
5 1 2 3 4
10 2 4 6 8
15 3 6 9 12
20 4 8 12 16
25 5 10 15 20
circshift() 還有一個修改版本,circshift!
設定陣列的內容
[edit | edit source]要設定陣列的內容,在賦值表示式的左側指定索引
julia> a = collect(1:10); julia> a[9]= -9 -9
要檢查陣列是否真的發生了改變
julia> print(a) [1,2,3,4,5,6,7,8,-9,10]
你可以使用廣播賦值運算子一次性設定多個元素
julia> a[3:6] .= -5
4-element view(::Array{Int64,1}, 3:6) with eltype Int64:
-5
-5
-5
-5
julia> print(a)
[1,2,-5,-5,-5,-5,7,8,-9,10]
你還可以將一系列元素設定為適合的一系列值
julia> a[3:9] = collect(9:-1:3)
7-element Array{Int64,1}:
9
8
7
6
5
4
3
注意,雖然 Julia 顯示 7 元素切片作為返回值,但實際上整個陣列已被修改
julia> a
10-element Array{Int64,1}:
1
2
9
8
7
6
5
4
3
10
可以使用廣播將範圍設定為單個值
julia> a[1:5] .= 0 0
julia> a
10-element Array{Int64,1}:
0
0
0
0
0
6
7
8
9
10
julia> a[1:10] .= -1; -1
julia> print(a) [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
作為方括號表示法的替代方法,有一個函式呼叫版本可以完成相同的設定陣列內容的工作,setindex!()
julia> setindex!(a, 1:10, 10:-1:1)
10-element Array{Int64,1}:
10
9
8
7
6
5
4
3
2
1
你可以使用冒號分隔符而不帶起始和結束索引號來引用陣列的全部內容,即 [:]。例如,建立陣列 a 後
julia> a = collect(1:10);
我們可以使用 a[:] 來引用該陣列 a 的內容
julia> b = a[:]
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
julia> b[3:6]
4-element Array{Int64,1}:
3
4
5
6
將陣列傳遞給函式
[edit | edit source]函式無法修改作為引數傳遞給它的變數,但可以改變傳遞給它的容器的內容。
考慮以下函式,它將它的引數更改為 5
julia> function set_to_5(x)
x = 5
end
set_to_5 (generic function with 1 method)
julia> x = 3 3
julia> set_to_5(x) 5
julia> x 3
雖然函式內部的 x 被改變了,但函式外部的 x 沒有被改變。函式中的變數名稱是區域性的。
但是,你可以修改容器的內容,例如陣列。下一個函式使用 [:] 語法來訪問容器 x 的內容,而不是改變變數 x 的值
julia> function fill_with_5(x)
x[:] .= 5
end
fill_with_5 (generic function with 1 method)
julia> '''x = collect(1:10)'''
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
julia> '''fill_with_5(x)'''
5
julia> '''x'''
10-element Array{Int64,1}:
5
5
5
5
5
5
5
5
5
5
如果你嘗試改變變數本身,而不是訪問容器變數的內容,它將不起作用。例如,以下函式定義在 temp 中建立一個由 5 組成的陣列,然後嘗試將引數 x 更改為 temp。
julia> function fail_to_fill_with_5(x)
temp = similar(x)
for i in eachindex(x)
temp[i] = 5
end
x = temp
end
fail_to_fill_with_5 (generic function with 1 method)
julia> x = collect(1:10)
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
julia> fail_to_fill_with_5(x)
10-element Array{Int64,1}:
5
5
5
5
5
5
5
5
5
5
看起來它工作了,但是
julia> x
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
你可以改變陣列中的元素,但你不能改變變數,使其指向另一個數組。換句話說,你的函式不允許改變引數和傳遞給它的陣列之間的繫結。
Julia 處理函式引數的方式被稱為“按共享傳遞”。當你將陣列傳遞給函式時,它不會被複制(對於大型陣列來說,這將非常低效)。
矩陣運算
[edit | edit source]對於矩陣對矩陣的運算,你可以
- 加 (+) 和減 (-)
julia> A = reshape(1:12, 3, 4)
3x4 Array{Int64,2}:
1 4 7 10
2 5 8 11
3 6 9 12
|
|
julia> B = ones(3,4)
3x4 Array{Float64,2}:
1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0
|
|
julia> A + B
3x4 Array{Float64,2}:
2.0 5.0 8.0 11.0
3.0 6.0 9.0 12.0
4.0 7.0 10.0 13.0
|
|
julia> A - B
3x4 Array{Float64,2}:
0.0 3.0 6.0 9.0
1.0 4.0 7.0 10.0
2.0 5.0 8.0 11.0
|
|
- 乘 (*),假設維度相容,因此 m1 * m2 是可能的,如果 last(size(m1)) == first(size(m2))。注意矩陣乘法和元素級矩陣乘法之間的區別。這是一個矩陣 A
julia> A = [1 2 ; 3 4]
2x2 Array{Int64,2}:
1 2
3 4
|
|
還有矩陣 `B`
julia> B = [10 11 ; 12 13]
2x2 Array{Int64,2}:
10 11
12 13
|
|
.* 廣播運算子逐元素相乘
julia> A .* B
2x2 Array{Int64,2}:
10 22
36 52
|
|
與矩陣乘法 `A * B` 相比
julia> A * B
2x2 Array{Int64,2}:
34 37
78 85
|
|
是
julia> [1 * 10 + 2 * 12 1 * 11 + 2 * 13 ; 3 * 10 + 4 * 12 3 * 11 + 4 * 13]
2x2 Array{Int64,2}:
34 37
78 85
- 兩個矩陣的除法。可以使用反斜槓 (\) 進行左除
julia> A = rand(1:9, 3, 3)
3x3 Array{Int64,2}:
5 4 3
8 7 7
9 3 7
julia> B = rand(1:9, 3, 3)
3x3 Array{Int64,2}:
6 5 5
6 7 5
7 2 7
julia> A \ B
3x3 Array{Float64,2}:
2.01961 0.411765 1.84314
0.254902 1.35294 -0.0392157
-1.70588 -0.823529 -1.35294
以及正斜槓 (/) 進行右除或斜除
julia> A / B
3x3 Array{Float64,2}:
4.0 -2.0 -1.0
0.285714 0.714286 0.285714
5.07143 -3.07143 -0.428571
對於矩陣和標量,可以進行加、減、乘和除運算
julia> A + 1
3x3 Array{Int64,2}:
6 5 4
9 8 8
10 4 8
julia> [1 2 3 4 5] * 2
1x5 Array{Int64,2}:
2 4 6 8 10
julia> A .- 1
3x3 Array{Int64,2}:
4 3 2
7 6 6
8 2 6
julia> A .* 2
3x3 Array{Int64,2}:
10 8 6
16 14 14
18 6 14
julia> A ./ 2
3x3 Array{Float64,2}:
2.5 2.0 1.5
4.0 3.5 3.5
4.5 1.5 3.5
等等
julia> A // 2
3x4 Array{Rational{Int64},2}:
1//2 2//1 7//2 5//1
1//1 5//2 4//1 11//2
3//2 3//1 9//2 6//1
julia> A .< 6
3x3 BitArray{2}:
true true true
false false false
false true false
如果陣列具有相容的形狀,則可以將矩陣乘以向量(矩陣向量積)。這是矩陣 A
julia> A = reshape(1:12, 3, 4)
3x4 Array{Int64,2}:
1 4 7 10
2 5 8 11
3 6 9 12
|
|
這是向量 V
julia> V = collect(1:4)
4-element Array{Int64,1}:
1
2
3
4
|
|
* 運算子將它們相乘
julia> A * V
3-element Array{Int64,1}:
70
80
90
|
|
可以使用 `dot()` 函式找到點積或內積 (aTb),但首先需要匯入 LinearAlgebra 庫
julia> using LinearAlgebra
julia> dot([1:3...], [21:23...])
134
|
|
julia> (1 * 21) + (2 * 22) + (3 * 23) 134
兩個引數的長度必須相同。也可以使用點運算子,在 REPL 中,可以透過輸入 "\cdot" 然後按 Tab 鍵獲得點運算子
julia> [1:3] ⋅ [21:23] 134
連線陣列和矩陣
[edit | edit source]如果矩陣的維度允許,可以使用 `hcat()` 和 `vcat()` 將它們連線在一起。
hcat() 保留第一維並擴充套件(連線)第二維,vcat() 保留第二維並擴充套件第一維。
這是兩個 3×4 矩陣
julia> A = reshape(1:12, 3, 4)
3x4 Array{Int64,2}:
1 4 7 10
2 5 8 11
3 6 9 12
julia> B = reshape(100:100:1200, 3, 4)
3x4 Array{Int64,2}:
100 400 700 1000
200 500 800 1100
300 600 900 1200
hcat(A, B) 建立一個新的陣列,該陣列仍然具有 3 行,但擴充套件/連線列,使總列數為 8
julia> hcat(A, B)
3x8 Array{Int64,2}:
1 4 7 10 100 400 700 1000
2 5 8 11 200 500 800 1100
3 6 9 12 300 600 900 1200
vcat(A, B) 建立一個新的陣列,該陣列保留 4 列,但擴充套件到 6 行
julia> vcat(A, B)
6x4 Array{Int64,2}:
1 4 7 10
2 5 8 11
3 6 9 12
100 400 700 1000
200 500 800 1100
300 600 900 1200
你可能會發現快捷方式很有用
- [A ; B ] 是
vcat(A, B) - [A B ] 是
hcat(A, B)
vec() 將矩陣扁平化為向量,將其轉換為(有些人稱之為“列”)向量
julia> vec(ones(3, 4))
12-element Array{Float64,1}:
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
還有一個 `hvcat()` 函式 ([A B; C D;]),它同時執行這兩項操作。
可以使用 `hcat()` 將陣列的陣列轉換為矩陣(使用 hcat-splat)
julia> a = Array[[1, 2], [3, 4], [5, 6]]
3-element Array{Array{T,N},1}:
[1, 2]
[3, 4]
[5, 6]
julia> hcat(a...)
2x3 Array{Int64,2}:
1 3 5
2 4 6
Julia 陣列是“列優先”的。這意味著你從上到下讀取列
1 3 2 4
而“行優先”陣列是從左到右讀取的,例如
1 2 3 4
Fortran、R、Matlab、GNU Octave 以及 BLAS 和 LAPACK 引擎(“高效能數值計算的核心”)使用列優先順序。C/C++、Mathematica、Pascal、Python、C#/CLI/.Net 等語言使用行優先順序。
擴充套件陣列
[edit | edit source]通常,你希望建立一個數組,然後向其中新增更多元素或“擴充套件”它。雖然可以使用 vcat() 和 hcat() 完成此操作,但請注意,這兩個操作都會建立新的臨時陣列並複製元素,因此它們並不總是能生成最快的程式碼。更好的方法是使用 `push!`。這是一個高效的操作,可以擴充套件陣列。之後可以對陣列進行重塑
julia> a = []
julia> for i = 1:80
push!(a, i)
end
julia> a
80-element Array{Any,1}:
1
2
3
4
5
6
7
8
9
⋮
75
76
77
78
79
80
reshape() 允許你更改陣列的維度。可以提供維度,也可以使用冒號 (:) 讓 Julia 計算有效的維度
julia> reshape(a, 10, :)
10x8 Array{Any,2}:
1 11 21 31 41 51 61 71
2 12 22 32 42 52 62 72
3 13 23 33 43 53 63 73
4 14 24 34 44 54 64 74
5 15 25 35 45 55 65 75
6 16 26 36 46 56 66 76
7 17 27 37 47 57 67 77
8 18 28 38 48 58 68 78
9 19 29 39 49 59 69 79
10 20 30 40 50 60 70 80
reshape(a, (10, div(length(a), 10))) 將產生相同的效果。
push!() 無法將新行推送到二維陣列或矩陣。完成此任務的最佳方法是像上面一樣操作一維陣列,在末尾新增更多元素,然後使用 `reshape()` 將其轉換為二維。如果需要,可以使用 `transpose()` 翻轉矩陣。
要轉置陣列或矩陣,有一個等效的'運算子用於transpose()函式,用於交換行和列
julia> M = reshape(1:12, 3, 4)
3×4 Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}:
1 4 7 10
2 5 8 11
3 6 9 12
julia> transpose(M)
4x3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
10 11 12
julia> M'
4x3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
10 11 12
要查詢方陣的行列式,請使用det(),在使用之前請記住載入LinearAlgebra庫。
julia> using LinearAlgebra
julia> A = rand(2:10, 3, 3)
3x3 Array{Int64,2}:
8 8 2
6 9 6
9 2 10
julia> det(A) 438.00000000000006
inv()(在標準庫中)查詢方陣的逆矩陣(如果存在)。(如果矩陣的行列式為零,則它將沒有逆矩陣。)
julia> inv(A)
3x3 Array{Float64,2}:
0.178082 -0.173516 0.0684932
-0.0136986 0.141553 -0.0821918
-0.157534 0.127854 0.0547945
LinearAlgebra.rank() 查詢矩陣的秩,LinearAlgebra.nullspace() 查詢零空間的基礎。
julia> A
3x4 Array{Int64,2}:
1 4 7 10
2 5 8 11
3 6 9 12
julia> rank(A) 2
julia> nullspace(A)
4x2 Array{Float64,2}:
-0.475185 -0.272395
0.430549 0.717376
0.564458 -0.617566
-0.519821 0.172585
LinearAlgebra.tr() 求和方陣的對角線(跡)
julia> s = reshape(1:9, 3, 3)
3x3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
julia> tr(s) 15
有許多函式可以應用於矩陣
- sum() 將所有元素加起來
julia> A = reshape(1:9, 3, 3)
3×3 Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}:
1 4 7
2 5 8
3 6 9
julia> sum(A) 45
如果要僅求和列或行,則可以指定一個維度。因此,要求和列,請指定維度 1
julia> sum(A, dims=(1))
1x3 Array{Int64,2}:
6 15 24
要求和行,請指定維度 2
julia> sum(A, dims=(2))
3x1 Array{Int64,2}:
12
15
18
- mean() 查詢矩陣中值的平均值
julia> using Statistics; mean(A) 5.0
與 sum() 一樣,您可以指定一個維度,以便可以查詢列的平均值(使用維度 1)或行的平均值(使用維度 2)
julia> mean(A, dims=(1))
1x3 Array{Float64,2}:
2.0 5.0 8.0
julia> mean(A, dims=(2))
3x1 Array{Float64,2}:
4.0
5.0
6.0
- min.(A, B) 和 max.(A, B) 函式逐元素比較兩個(或更多)陣列,返回一個包含每個元素中最大值(或最小值)的新陣列
julia> A = rand(-1:2:1, 3, 3)
3x3 Array{Int64,2}:
-1 -1 -1
-1 1 1
1 -1 1
julia> B = rand(-2:4:2, 3, 3)
3x3 Array{Int64,2}:
2 2 2
2 -2 2
2 2 2
julia> min.(A, B)
3×3 Array{Int64,2}:
1 -2 -2
-1 -2 -1
1 1 -1
julia> max.(A, B)
3×3 Array{Int64,2}:
2 1 1
2 1 2
2 2 2
prod() 將矩陣的元素相乘
julia> A = reshape(collect(BigInt(1):25), 5, 5)
5×5 Array{BigInt,2}:
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
julia> prod(A)
15511210043330985984000000
(注意 BigInt 的使用,乘積非常大。)
如果要僅將列或行的元素相乘,則可以指定一個維度。要將列的元素相乘,請指定維度 1;對於行,請使用維度 2
julia> prod(A, dims=1)
1x5 Array{Int64,2}:
120 30240 360360 1860480 6375600
julia> prod(A, dims=2)
5x1 Array{Int64,2}:
22176
62832
129168
229824
375000
大多數這些函式都位於 LinearAlgebra 庫中
julia> using LinearAlgebra
歐幾里得範數,,由 LinearAlgebra.norm(x) 查詢
julia> X = [2, 4, -5]
3-element Array{Int64,1}:
2
4
-5
julia> LinearAlgebra.norm(X) # Euclidean norm
6.708203932499369
julia> LinearAlgebra.norm(X, 1) # 1-norm of the vector, the sum of element magnitudes
11.0
如果 X 是一個“行”向量
julia> X = [2 4 -5]
1x3 Array{Int64,2}:
2 4 -5
julia> LinearAlgebra.norm(X)
6.708203932499369
julia> LinearAlgebra.norm(X, 1)
11.0
向量 和 之間的歐幾里得距離,由 給出,由 norm(x - y) 查詢
julia> LinearAlgebra.norm([1 2 3] - [2 4 6]) 3.741657386773941 julia> LinearAlgebra.norm([1, 2, 3] - [2, 4, 6]) 3.741657386773941
兩個向量 和 之間的夾角為
acos(dot(a,b)/(norm(a)*norm(b)))
以下是矩陣的 1-範數(最大絕對列之和)
julia> B = [5 -4 2 ; -1 2 3; -2 1 0]
3x3 Array{Int64,2}:
5 -4 2
-1 2 3
-2 1 0
julia> LinearAlgebra.opnorm(B, 1) 8.0
以下是無窮範數(最大絕對行之和)
julia> LinearAlgebra.opnorm(B, Inf) 11.0
請注意,它們不同於向量化的 1-範數或無窮範數
julia> LinearAlgebra.norm(B, 1) 20.0
julia> LinearAlgebra.norm(B, Inf) 5.0
歐幾里得 norm() 是預設值
julia> LinearAlgebra.norm([2 3 ; 4 6]), LinearAlgebra.opnorm([2 3 ; 4 6]), sqrt(2^2 + 3^2 + 4^2 + 6^2) (8.062257748298547,8.062257748298547,8.06225774829855)
- rmul!(A, n) 將矩陣的每個元素就地縮放一個縮放因子 n
julia> A = [1 2 3
4 5 6
7 8 9]
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
julia> rmul!(A, 2)
3×3 Array{Int64,2}:
2 4 6
8 10 12
14 16 18
還有旋轉和迴圈移位函式
julia> A = [1 2 3
4 5 6
7 8 9]
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
julia> rot180(A)
3×3 Array{Int64,2}:
9 8 7
6 5 4
3 2 1
julia> circshift(A, (1, 1))
3×3 Array{Int64,2}:
9 7 8
3 1 2
6 4 5
julia> A
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
reverse() 會建立矩陣的副本,反轉行或列
julia> reverse(A, dims=(1))
3×3 Array{Int64,2}:
7 8 9
4 5 6
1 2 3
julia> reverse(A, dims=(2))
3×3 Array{Int64,2}:
3 2 1
6 5 4
9 8 7
squeeze() 和 reshape() 可用於更改矩陣的維度。例如,以下是如何使用 squeeze() 將行向量(1 x 4)壓縮為 4 x 1 陣列
julia> a = [1 2 3 4]
1x4 Array{Int64,2}:
1 2 3 4
julia> ndims(a) 2
julia> b = squeeze(a, dims=(1))
4-element Array{Int64,1}:
1
2
3
4
julia> ndims(b) 1
Julia 具有靈活的 sort() 函式,該函式返回陣列的已排序副本,還有一個配套的 sort!() 版本,該版本會更改陣列使其已排序。
通常可以使用 sort() 而不使用任何選項,並獲得期望的結果
julia> using Random
julia> rp = randperm(10)
10-element Array{Int64,1}:
6
4
7
3
10
5
8
1
9
2
julia> sort(rp)
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
您可以對二維陣列進行排序
julia> a = reshape(rand(1:20, 20), 4, 5)
4x5 Array{Int64,2}:
19 13 4 10 10
6 20 19 18 12
17 7 15 14 9
1 16 8 7 13
julia> sort(a, dims=(1)) # sort each column, dimension 1
4x5 Array{Int64,2}:
1 7 4 7 9
6 13 8 10 10
17 16 15 14 12
19 20 19 18 13
julia> sort(a, dims=(2)) # sort each row, dimension 2
4x5 Array{Int64,2}:
4 10 10 13 19
6 12 18 19 20
7 9 14 15 17
1 7 8 13 16
但 sortrows() 和 sortcolumns() 中有更強大的替代方法——有關詳細資訊,請參見下文。
sortperm() 函式類似於 sort(),但它不返回集合的已排序副本。相反,它返回一個索引列表,可以應用於集合以生成已排序版本
julia> r = rand(100:110, 10)
10-element Array{Int64,1}:
103
102
110
108
108
108
104
109
106
106
julia> sortperm(r)
10-element Array{Int64,1}:
2
1
7
9
10
4
5
6
8
3
julia> r[sortperm(r)]
10-element Array{Int64,1}:
102
103
104
106
106
108
108
108
109
110
如果需要超出預設 sort() 的功能,請使用 by 和 lt 關鍵字,併為排序期間的元素處理和比較提供自己的函式。
by 函式在比較之前會處理每個元素,併為排序提供“鍵”。一個典型的示例是將字串形式的數字列表按數值順序排序的任務。以下是該列表
julia> r = ["1E10", "150", "25", "3", "1.5", "1E-10", "0.5", ".999"];
如果使用預設排序,則數字將按 Unicode/ASCII 中字元出現的順序顯示
julia> sort(r)
8-element Array{ASCIIString,1}:
".999"
"0.5"
"1.5"
"150"
"1E-10"
"1E10"
"25"
"3"
其中“1E-10”出現在“0.999”之後。
要按數字的值對其進行排序,請將 parse() 函式(來自 Meta 包)傳遞給 by
julia> sort(r, by = x -> Meta.parse(x))
8-element Array{String,1}:
"1E-10"
"0.5"
".999"
"1.5"
"3"
"25"
"150"
"1E10"
字串按其值排序。請注意,您提供的by函式會生成數值排序鍵,但最終結果中會顯示原始字串元素。
匿名函式在排序陣列時很有用。下面是一個 10 行 2 列的元組陣列。
julia> table = collect(enumerate(rand(1:100, 10)))
10-element Array{(Int64,Int64),1}:
(1,86)
(2,25)
(3,3)
(4,97)
(5,89)
(6,58)
(7,27)
(8,93)
(9,98)
(10,12)
您可以透過向by提供一個指向每個元組第二元素的匿名函式,按每個元組的第二個元素而不是第一個元素對該陣列進行排序。匿名函式表示,給定要排序的物件x,按x的第二個元素進行排序。
julia> sort(table, by = x -> x[2])
10-element Array{(Int64,Int64),1}:
(3,3)
(10,12)
(2,25)
(7,27)
(6,58)
(1,86)
(5,89)
(8,93)
(4,97)
(9,98)
按多列排序
[edit | edit source]如果您想按多列排序,可以在by函式中提供一個“列”識別符號元組。
julia> a = [[2, 2, 2, 1],
[1, 1, 1, 8],
[2, 1, 2, 2],
[1, 2, 2, 5],
[2, 1, 1, 4],
[1, 1, 2, 7],
[1, 2, 1, 6],
[2, 2, 1, 3]] ;
julia> sort(a, by = col -> (col[1], col[2], col[3]))
8-element Array{Array{Int64,1},1}:
[1,1,1,8]
[1,1,2,7]
[1,2,1,6]
[1,2,2,5]
[2,1,1,4]
[2,1,2,2]
[2,2,1,3]
[2,2,2,1]
這將首先按列 1 排序陣列,然後按列 2 排序,最後按列 3 排序。
重新定義“小於”
[edit | edit source]預設情況下,排序在比較元素時使用內建的isless()函式。在排序後的陣列中,第一個元素小於第二個元素。
您可以透過將不同的函式傳遞給lt關鍵字來更改此行為。此函式應比較兩個元素,如果它們已排序,則返回 true,即如果第一個元素“小於”第二個元素(使用某種“小於”定義)。排序過程會重複比較元素對,直到陣列中的每個元素都處於正確位置。
例如,假設您想根據每個單詞中的母音數量對單詞陣列進行排序;也就是說,母音數量越多的單詞,在排序結果中出現的越早。例如,單詞“orange”將被視為“小於”單詞“lemon”,因為它包含更多母音。
首先,我們需要一個計算母音數量的函式
vowelcount(string) = count(c -> (c in "aeiou"), lowercase(string))
現在,您可以將一個匿名函式傳遞給sort(),該函式使用此函式比較兩個元素的母音數量,然後在每種情況下返回母音數量較多的元素
sentence = split("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
sort(sentence, lt = (x,y) -> vowelcount(x) > vowelcount(y))
結果是母音數量最多的單詞將出現在最前面
19-element Array{SubString{String},1}:
"adipisicing"
"consectetur"
"eiusmod"
"incididunt"
"aliqua."
"labore"
"dolore"
"Lorem"
"ipsum"
"dolor"
"amet,"
"elit,"
"tempor"
"magna"
"sit"
"sed"
"do"
"ut"
"et"
sort()函式還允許您指定反向排序 - 在by和lt函式(如果使用)完成其工作後,傳遞給rev的 true 值將反轉結果。
排序二維陣列
[edit | edit source]在 Julia 1.0 中,您可以使用sortslices()對多維陣列進行排序。
下面是一個包含九個字串的簡單陣列(您也可以使用數字、符號、函式或任何可以比較的內容)
julia> table = ["F" "B" "I"; "A" "D" "G"; "H" "C" "E"]
3×3 Array{String,2}:
"F" "B" "I"
"A" "D" "G"
"H" "C" "E"
您可以向dims(“維度”)關鍵字提供一個數字或一個元組,以指示要排序的內容。要排序表以使第一列排序,請使用1
julia> sortslices(table, dims=1)
3×3 Array{String,2}:
"A" "D" "G"
"F" "B" "I"
"H" "C" "E"
請注意,sortslices會返回一個新陣列。第一列按字母順序排列。
使用dims=2對錶進行排序,以使第一行排序
julia>> sortslices(table, dims=2)
3×3 Array{String,2}:
"B" "F" "I"
"D" "A" "G"
"C" "H" "E"
現在第一行按字母順序排列。
如果您想按第一項以外的其他內容進行排序,請將一個函式傳遞給by。因此,要按行排序,以使中間列按字母順序排列,請使用
julia> sortslices(table, dims=1, by = x -> x[2])
3×3 Array{String,2}:
"F" "B" "I"
"H" "C" "E"
"A" "D" "G"
sortslices具有您在sort中找到的大多數選項,以及更多。您可以使用rev反轉順序,使用lt更改比較器,等等。
元組
[edit | edit source]元組是元素的有序序列,類似於陣列。元組由圓括號和逗號表示,而不是陣列使用的方括號。元組通常適合於小型固定長度的集合 - 它們在 Julia 中無處不在,例如作為引數列表以及從函式返回多個值。
陣列和元組之間最重要的區別是元組是不可變的。除此之外,元組的工作方式與陣列非常相似,許多陣列函式也可以在元組上使用。
julia> t = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (1,2,3,4,5,6,7,8,9,10)
julia> t (1,2,3,4,5,6,7,8,9,10)
julia> t[6:end] (6,7,8,9,10)
您可以擁有二維元組
julia> t = ((1, 2), (3, 4)) ((1,2),(3,4))
julia> t[1] (1,2)
julia> t[1][2] 2
但是您無法更改元組
julia> t[1] = 0 LoadError: MethodError: no method matching set index!...
而且,由於您無法修改元組,因此您無法使用與陣列一起使用的任何函式(例如push!())。
julia> a = [1,2,3];
julia> push!(a,4)
4-element Array{Int64,1}:
1
2
3
4
julia> t = (1,2,3); julia> push!(t,4) LoadError: MethodError: no method matching push!
命名元組
[edit | edit source]命名元組類似於元組和字典的組合。與元組一樣,命名元組是有序且不可變的,並用圓括號括起來;與字典一樣,每個元素都有一個唯一的鍵,可用於訪問它。
您可以透過直接提供鍵和值來建立命名元組
julia> shape1 = (corner1 = (1, 1), corner2 = (-1, -1), center = (0, 0)) (corner1 = (1, 1), corner2 = (-1, -1), center = (0, 0))
要訪問值,請使用熟悉的點語法
julia> shape1.corner1 (1, 1) julia> shape1.center (0, 0) julia> (shape1.corner1, shape1.corner2) ((1, 1), (-1, -1))
您可以像普通元組一樣訪問所有值(解構)
julia> c1, c2, centerp = shape1; julia> c1 (1, 1) julia> c2 (-1, -1)
或者只訪問其中一些
julia> c1, c2 = shape1; julia> c1 (1, 1)
julia> c2 (-1, -1)
元素可以是相同型別,也可以是不同型別,但鍵始終是變數名。
您可以遍歷命名元組
julia> for i in shape1
@show i
end
i = (1, 1)
i = (-1, -1)
i = (0, 0)
julia> for i in shape1
println(first(i))
end
1
-1
0
建立命名元組的另一種方法是在單獨的元組中提供鍵和值
julia> ks = (:corner1, :corner2)
(:corner1, :corner2)
julia> vs = ((10, 10), (20, 20))
((10, 10), (20, 20))
julia> shape2 = NamedTuple{ks}(vs)
(corner1 = (10, 10), corner2 = (20, 20))
julia>shape2.corner1
(10, 10)
julia> shape2.corner2
(20, 20)
您可以組合兩個命名元組以建立一個新的命名元組
julia> colors = (top = "red", bottom = "green") (top = "red", bottom = "green") julia> merge(shape2, colors) (corner1 = (10, 10), corner2 = (20, 20), top = "red", bottom = "green")
您可以使用現有變數作為鍵
julia> d = :density; julia> (corner1 = (10, 10), corner2 = (20, 20), d => 0.99)
(corner1 = (10, 10), corner2 = (20, 20), density = 0.99)
建立單個值的命名元組需要一個策略性放置的逗號
julia> shape3 = (corner1 = (1, 1),) (corner1 = (1, 1),)
julia> typeof(shape3)
NamedTuple{(:corner1,),Tuple{Tuple{Int64,Int64}}}
如果您忘記它,您將看到此提示
julia> (corner1 = (1, 1))
(1, 1)
julia> typeof(corner1)
Tuple{Int64,Int64}
您可以透過將命名元組組合在一起建立新的命名元組。
julia> shape3 = merge(shape2, colors) (corner1 = (10, 10), corner2 = (20, 20), top = "red", bottom = "green")
在單個元素命名元組之後使用逗號
julia> merge(shape2, (top = "green",)) (corner1 = (10, 10), corner2 = (20, 20), top = "green")
因為如果沒有逗號,元組將被解釋為merge()的括號括起來的關鍵字引數。
要遍歷“鍵”,請使用fieldnames()和typeof()函式
julia> fieldnames(typeof(shape3)) (:corner1, :corner2, :top, :bottom)
所以您可以執行以下操作
julia> for key in fieldnames(typeof(shape3))
@show getindex(shape3, key)
end
getindex(shape3, key) = (10, 10)
getindex(shape3, key) = (20, 20)
getindex(shape3, key) = "red"
getindex(shape3, key) = "green"
合併兩個元組的方式非常智慧。例如,如果您有以下命名元組
julia> shape3 (corner1 = (10, 10), corner2 = (20, 20), top = "red", bottom = "green")
並且您想新增一箇中心點並更改頂部顏色
julia> merge(shape3, (center = (0, 0), top="green")) (corner1 = (10, 10), corner2 = (20, 20), top = "green", bottom = "green", center = (0, 0))
將插入新值,並更改現有值。
使用命名元組作為關鍵字引數
[edit | edit source]命名元組是將一組關鍵字引數傳遞給函式的便捷方式。下面是一個接受三個關鍵字引數的函式
function f(x, y, z; a=10, b=20, c=30)
println("x = $x, y = $y, z = $z; a = $a, b = $b, c = $c")
end
您可以定義一個命名元組,其中包含一個或多個關鍵字的名稱和值
options = (b = 200, c = 300)
要將命名元組傳遞給函式,請在呼叫函式時使用;
f(1, 2, 3; options...) x = 1, y = 2, z = 3; a = 10, b = 200, c = 300
如果您指定關鍵字和值,則它可以被後面的定義覆蓋
f(1, 2, 3; b = 1000_000, options...) x = 1, y = 2, z = 3; a = 1000, b = 200, c = 300
f(1, 2, 3; options..., b= 1000_000) x = 1, y = 2, z = 3; a = 10, b = 1000000, c = 300