Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

この記事について

この記事は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で面白い話がありましたら教えてください。
また、本記事の中で間違えている点がございましたら、ご指摘ください。

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

yokotate
専門学校からなんとなくIT企業に入社した万年素人SE(自称)。Pythonは業務で使ってないのに業務で使ってる言語よりも使っている時間が長い気がするのが最近の悩み。 最近はAI系の技術に興味を持ちつつも日々自分の基礎学力無さに嘆いている。 書く内容はほぼ初心者向け。投稿する記事の内容は個人の意見であり、所属する企業の見解を代表するものではありません。
https://github.com/yokotate
japan-systems
「2019年に50周年を迎えたIT企業です。最先端の技術により全国の企業、官公庁、自治体に多くの実績があります。」
https://www.japan-systems.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした