LoginSignup
3
1

More than 5 years have passed since last update.

JuliaのArray型を弄ってみる(書き直し中)

Last updated at Posted at 2019-03-15

この記事について

この記事はJuliaのArray型を使ってみるというものです。
書き方について混乱をしたところがあるので書いてみようと思います。
今なお混乱してますが。

最後のまとめでは使用感と個人的な使用方法について書いております。

本編

Arrayの書き方色々(1次元)

JuliaでのArrayの書き方はいろいろあります。

Array
# 基本的な形
julia> l1 = [1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

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

すでに何か異なりますね。
「,」で区切るとベクトル的な値の持ち方ですが、「 」で区切ると1 * 3となり行列のような持ち方をしているように見えます。これは値の取得方法を見るとわかります。

Array
# 値を取得
julia> l1[1]
1

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

julia> l1[1,2]
ERROR: BoundsError: attempt to access 3-element Array{Int64,1} at index [1, 2]
Stacktrace:
 [1] getindex(::Array{Int64,1}, ::Int64, ::Int64) at .\array.jl:732
 [2] top-level scope at none:0

ベクトルであるl1の場合、[1,2]のように値を取得して来ようとするとエラーが出ます。
次にl2でどのようになるのかを見てみましょう

Array
julia> l2[1]
1

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

julia> l2[1,2]
2

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

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

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

どうやら取得する方法によっても行列として取得するのかベクトルとして出力するのかが選べるようです。
[1.1:3]のように取得するとベクトルですが、[1:1,1:3]で取得すると行列ですね。

Arrayの書き方色々(2次元)

とりあえずArrayの基本的な記述方法についてはわかりましたので、次に行こうと思います。
つまりは二次元配列の実装です。
では「,」区切りの場合を見てみます。先ほどではベクトルとして出力されてしまいましたが、二次元配列として入れるとどうなるのでしょうか。

「,(カンマ)」区切りの場合

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

あれ、Arrayの中にArrayが入ってしまいました。
でもまぁ行けるんじゃないかな?

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

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

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

julia> l1[1,2]
ERROR: BoundsError: attempt to access 2-element Array{Array{Int64,1},1} at index [1, 2]
Stacktrace:
 [1] getindex(::Array{Array{Int64,1},1}, ::Int64, ::Int64) at .\array.jl:732
 [2] top-level scope at none:0

julia> l1[1][2]
2

値の取得のされ方が「 」で区切ったデータと異なりますね。
少しモヤモヤしますがここはスルーして、よく使用する転置をしてみようと思います。

Array
julia> l1
2-element Array{Array{Int64,1},1}:
 [1, 2, 3]
 [4, 5, 6]
julia> l1'
1×2 LinearAlgebra.Adjoint{LinearAlgebra.Adjoint{Int64,Array{Int64,1}},Array{Array{Int64,1},1}}:
 [1 2 3]  [4 5 6]

なるほど、これはダメみたいですね。
Arrayの中にArrayが入ってしまっているので、外側のArrayだけが転置されてしまっているようです。
他にも試してみましょう

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

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

l1 = [[1,2,3];[4,5,6]]はどう頑張っても二次元配列にはならなそうです。
l1 = [[1,2,3] [4,5,6]]なら転置したら行けそうですね

Array
julia> rl = l1'
2×3 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}:
 1  2  3
 4  5  6

julia> rl
2×3 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}:
 1  2  3
 4  5  6

julia> rl[1,2]
2

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

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

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

これなら二次元配列として使用することが出来ますね!
こんな面倒なことしたくありません。

「 (半角スペース)」区切りの場合

「,」で区切るととても使いにくいことがわかりました。
なので「 」で区切って楽に二次元配列を取得しましょう。

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

くっついてしまいました。

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

Arrayの中にArrayが入ってしまいました。

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

ハイ出来ました!
これでできました!
何の問題もありませんでした!

Array
julia> l2[1]
1

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

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

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

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

値もしっかりと取得することが出来ています。
l2[1:4]がちょっと不思議な動き方をしていますが気にしません!

困ったこと

二次元配列を作ろうとした際に、Pythonユーザーだったので[[1,2,3],[4,5,6]]と記述をしていました。その際に困ったのがDataFramesでのArrayの取り扱いです。

Array
julia> df = DataFrame(l1)
3×2 DataFrame
 Row  x1     x2    
      Int64  Int64 
├─────┼───────┼───────┤
 1    1      4     
 2    2      5     
 3    3      6     

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

julia> df = DataFrame(l2)
2×3 DataFrame
 Row  x1     x2     x3    
      Int64  Int64  Int64 
├─────┼───────┼───────┼───────┤
 1    1      2      3     
 2    4      5      6     

l1を見ていただくとわかる通り、私の考えていたものと列と行が反対になって取り込まれてしまいました。
これなら転置すればいいだろうと思ったのですが、

Array
julia> df = DataFrame(l1')
1×2 DataFrame
 Row  x1         x2        
      LinearAl…  LinearAl… 
├─────┼───────────┼───────────┤
 1    [1 2 3]    [4 5 6]   

こうなりました。

まとめ

Arrayを簡単に触ってみたまとめです。
「,」区切りと「 」区切りの違いはなんとなく分かった気がします。

  • 配列ならば「,」を使用する
  • 行列ならば「 」を使用する
  • Juliaは配列と行列を明確に分けている?
  • 「,」を使用して多次元配列を作成することもできるが、データの取得方法が異なるので気を付けること(プロジェクト内で使用方法を統一する)
  • パッケージにArrayを送り付ける際にはどのようにデータが取り扱われているのかを調べること
  • 以下のような使い方もできるので「,」区切りをするなとは言えない
Array
julia> l3 = [[1,2,[3,4,5]],[6,7,[8,9,10]]]
2-element Array{Array{Any,1},1}:
 [1, 2, [3, 4, 5]]
 [6, 7, [8, 9, 10]]

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

julia> l3[1][2]
2

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

julia> l3[1][3][1]
3

画像とかの処理で使えそう?
「 」でこれを作ろうとすると2*5Arrayが作成されます。

おまけというか答えというか

Juliaのプログラム上でどのように扱われるのかを調べてみました

Array
function ArrayCheck(l::AbstractVector)
    println("vector")
end

function ArrayCheck(l::AbstractMatrix)
    println("Matrix")
end

l1 = [1,2,3]
l2 = [[1,2,3],[4,5,6]]
l3 = [1 2 3]

ArrayCheck(l1)
ArrayCheck(l2)
ArrayCheck(l3)
result
vector
vector
Matrix

最後に

JuliaでのArrayで面白い話がありましたら教えてください。
また、本記事の中で間違えている点がございましたら、ご指摘ください。

よろしくお願いいたします。

3
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1