この記事について
JuliaのArrayを色々と弄ってみました。
先日に挙げた記事が多くのご指摘をいただいたので、書き直してました。
これで合っているのか不安しかないですが。
本編
配列の書き方
Juliaでの行と列の書き方
Juliaでの配列の書き方は以下の通りです。
julia> l = [1 2 3;4 5 6]
2×3 Array{Int64,2}:
1 2 3
4 5 6
2行3列のデータを作成することが出来ました。
「 (半角スペース)」で区切ると行の表現になり、「;(セミコロン)」で区切ると列の表現になります。
「;」の代わりに改行をすることでも同様の表現をすることが出来ます。
julia> l = [1 2 3
4 5 6]
2×3 Array{Int64,2}:
1 2 3
4 5 6
JuliaでのArrayの値の取得
Arrayの値を取得します。
# 変数セット
julia> l = [1 2 3;4 5 6;7 8 9]
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
# 一つ目の値を取得
julia> l[1]
1
# 1~3の値を取得
julia> l[1:3]
3-element Array{Int64,1}:
1
4
7
# 1~4の値を取得
julia> l[1:4]
4-element Array{Int64,1}:
1
4
7
2
# 全部取得
julia> l[:]
9-element Array{Int64,1}:
1
4
7
2
5
8
3
6
9
# 1列目の値をすべて取得
julia> l[:,1]
3-element Array{Int64,1}:
1
4
7
# 1、2列目の値をすべて取得
julia> l[:,1:2]
3×2 Array{Int64,2}:
1 2
4 5
7 8
# 存在しない値は取得できない
julia> l[1:4,1]
ERROR: BoundsError: attempt to access 3×3 Array{Int64,2} at index [1:4, 1]
Stacktrace:
[1] throw_boundserror(::Array{Int64,2}, ::Tuple{UnitRange{Int64},Int64}) at .\abstractarray.jl:484
[2] checkbounds at .\abstractarray.jl:449 [inlined]
[3] _getindex at .\multidimensional.jl:596 [inlined]
[4] getindex(::Array{Int64,2}, ::UnitRange{Int64}, ::Int64) at .\abstractarray.jl:905
[5] top-level scope at none:0
# 1行目の値を取得する
julia> l[1,:]
3-element Array{Int64,1}:
1
2
3
値の取得をしようとするとまず列の値が取得されます。
列と行を指定したい場合には[列,行]の順番で指定する必要があります。
また、ベクトルへの変換(vec())を使用すると以下のようになります。
julia> vec(l)
9-element Array{Int64,1}:
1
4
7
2
5
8
3
6
9
ここまで教えていただいたことによって私はJuliaのArrayの取り扱いについてある程度理解することが出来ました。
Python(Numpy)をやっていて間違えたこと
PythonでNumpyを使用して行列を書く際に使用していた「,」を使って区切り、ネストして多次元配列を表現する方法がJuliaだと使用することが出来ませんでした。
julia> l = [[1,2,3],[4,5,6]]
2-element Array{Array{Int64,1},1}:
[1, 2, 3]
[4, 5, 6]
julia> l'
1×2 LinearAlgebra.Adjoint{LinearAlgebra.Adjoint{Int64,Array{Int64,1}},Array{Array{Int64,1},1}}:
[1 2 3] [4 5 6]
「,」での区切りは列の表現になってしまうそうで、ネストして記述すると列の中に列があるという表現になってしまうそうです。
最初に書いていた「;」の代わりに使用することはできません。
ただ、保持する内容は同じです。
julia> l = [1;2;3]
3-element Array{Int64,1}:
1
2
3
julia> l2 = [1,2,3]
3-element Array{Int64,1}:
1
2
3
# 半角スペース区切り
julia> l3 = [1 2 3]
1×3 Array{Int64,2}:
1 2 3
# 混ぜてみる
julia> l2 = [1 2,3 4]
ERROR: syntax: unexpected comma in matrix expression
列ベクトルとして保存されるので、これを使用して計算することも可能です。
julia> a = [1 2;3 4]
2×2 Array{Int64,2}:
1 2
3 4
julia> b = [2,3]
2-element Array{Int64,1}:
2
3
julia> a * b
2-element Array{Int64,1}:
8
18
# ;でも区切ってみる
julia> b = [2;3]
2-element Array{Int64,1}:
2
3
# 同じ結果になっている
julia> a * b
2-element Array{Int64,1}:
8
18
\Biggl(
\begin{matrix}
1 & 2\\
3 & 4
\end{matrix}
\Biggr)
\Biggl(
\begin{matrix}
2 \\ 3
\end{matrix}
\Biggr)
=
\Biggl(
\begin{matrix}
8 \\ 18
\end{matrix}
\Biggr)
Pythonとちょっとだけ比較
行指向のPythonと列指向のJuliaで動きの違いを見てみます。
>>> import numpy as np
>>> l = np.array([[1,2,3],[4,5,6]])
>>> l
array([[1, 2, 3],
[4, 5, 6]])
>>> l.flatten()
array([1, 2, 3, 4, 5, 6])
Pythonで2次元配列のデータをflattern()を使用してベクトルに変換しました。
出力された値は123456という順番です。
julia> l = [1 2 3;4 5 6]
2×3 Array{Int64,2}:
1 2 3
4 5 6
julia> vec(l)
6-element Array{Int64,1}:
1
4
2
5
3
6
Juliaで2次元配列のデータをvec()を使用してベクトルに変換しました。
出力された値は142536という順番です。
Pythonでは1行ずつ取り出して出力していますが、Juliaでは1列ずつ取り出して出力していることがわかりました。
まとめ
- 配列は基本的に「 」を区切り文字として使用する
- 配列の配列と多次元配列は別物
- Juliaは列指向と呼ばれるデータの持ち方をしている
お詫び
昨日投稿した記事につきまして、間違いがございましたことを謝罪いたします。
これに懲りることなく、今後もJulia入門記事を投稿し続けたいと考えておりますので、今後もアドバイスやミス指摘などをしてくださると大変うれしく思います!