LoginSignup
1
1

More than 5 years have passed since last update.

『機械学習のエッセンス(http://isbn.sbcr.jp/93965/)』のPythonサンプルをJuliaで書き換えてみる。(第04章02NumPyの基本)

Last updated at Posted at 2019-01-04

はじめに

『機械学習のエッセンス(http://isbn.sbcr.jp/93965/)』のPythonサンプルをJuliaで書き換えてみる。(第04章01数値計算の基本)の続きです。

※本との対比のため同じ見出しを付けていますが、NumPyではなくJuliaで書いているので以下の見出しからはNumPyは削除しています。

関数

  • eのべき乗
  • 自然対数
  • 正弦
  • 平方根
julia> exp(2)
7.38905609893065

julia> log()
1

julia> sin(π)
1.2246467991473532e-16

julia> sqrt(3)
1.7320508075688772

Juliaは「π」とか「ℯ」がそのまま使えるのが面白いですね。
日本語IMEだと「π」は”ぱい(pai)”と打って変換できますが、「ℯ」はいろいろ試したのですが変換できず、調べたらREPL上で\eulerと打って、Tabキーを押して変換できるようです。
上記のlog(ℯ)
log(\euler
まで打ってここでTabキーを押すと
log(ℯ
となりました。π\piですね。

配列

Juliaの配列のインデックスは「1」始まりなので、インデックス指定をするときPythonとは番号が異なります。なるべく本の結果と同じになるようにインデックスを調整しました。

julia> a = [2, 3, 5, 7, 8]
5-element Array{Int64,1}:
 2
 3
 5
 7
 8
  • 先頭の要素
julia> a[1]
2
  • インデックス2〜3の要素

julia> a[2:3]
2-element Array{Int64,1}:
 3
 5
  • インデックス3〜5-1=4までの要素
julia> a[3:-1]
0-element Array{Int64,1}

julia> a[3:end-1]
2-element Array{Int64,1}:
 5
 7

Juliaはインデックス「-1」は最後から−1の要素にならなく、endが最後のインデックスなのでend-1となります。

  • range指定の配列の作成。Juliaではcollect関数を使う。
julia> b = collect(0:4)
5-element Array{Int64,1}:
 0
 1
 2
 3
 4
  • ステップを0.2にする。

これもcollectを使います。Pythonと違ってSTEPを真ん中に書くとうまくいきました。

julia> c = collect(1:0.2:3)
11-element Array{Float64,1}:
 1.0
 1.2
 1.4
 1.6
 1.8
 2.0
 2.2
 2.4
 2.6
 2.8
 3.0

ただし、3まで指定すると最後の3自身が入るようです(Pythonの例では2.8まで)。同じ結果にするにはcollect(1:0.2:2.8)でしょうか。未満の書き方があるかはわかりませんでした。

  • 型の確認
julia> typeof(a)
Array{Int64,1}

julia> typeof(c)
Array{Float64,1}
  • 作成時に型を指定する。
julia> d = Float64[1, 2, 3]
3-element Array{Float64,1}:
 1.0
 2.0
 3.0

julia> typeof(d)
Array{Float64,1}
  • 引数に浮動小数点数を指定
julia> e = collect(0.:4.)
5-element Array{Float64,1}:
 0.0
 1.0
 2.0
 3.0
 4.0

julia> typeof(e)
Array{Float64,1}

2次元配列

2次元配列の操作

julia> a = Float64[2 3 4; 5 6 7]
2×3 Array{Float64,2}:
 2.0  3.0  4.0
 5.0  6.0  7.0
  • 第1行・第2列の要素
  • 第2列の全ての要素
  • 第2行の全ての要素
  • 第1行の第3列以降
  • 第1行の3列より前
julia> a[1, 2]
3.0

julia> a[:, 2]
2-element Array{Float64,1}:
 3.0
 6.0

julia> a[2, :]
3-element Array{Float64,1}:
 5.0
 6.0
 7.0

julia> a[1, 3:end]
1-element Array{Float64,1}:
 4.0

julia> a[1, 1:2]
2-element Array{Float64,1}:
 2.0
 3.0

最後の「第1行の3列より前」の書き方はわからず、インデックスの範囲指定にしました。

配列のデータ属性

  • 3行5列の2次元配列に変換
julia> a = reshape(collect(0.:14.), 3, 5)
3×5 Array{Float64,2}:
 0.0  3.0  6.0   9.0  12.0
 1.0  4.0  7.0  10.0  13.0
 2.0  5.0  8.0  11.0  14.0

※Pythonの行列表示とは転置状態になっています。

  • 配列の形状

Pythonのshapeにあたる関数はsizeでいけました。

julia> size(a)
(3, 5)
  • 配列の次元数
  • 要素数。これはsizeでなくlengthでした。
julia> ndims(a)
2

julia> length(a)
15
  • 1次元配列のまま
julia> b = collect(0.:3.)
4-element Array{Float64,1}:
 0.0
 1.0
 2.0
 3.0

julia> size(b)
(4,)

julia> ndims(b)
1

julia> length(b)
4

reshape関数と形状の変更

※本ではreshapeメソッドとなっていますが、Juliaでは関数の方があっていそうなので見出しは変更しました。

形状のいろいろな変更方法

julia> a = collect(0.:15.)
16-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
 11.0
 12.0
 13.0
 14.0
 15.0
  • 列数自動で形状の変更
julia> c = reshape(a, 4, :)
4×4 Array{Float64,2}:
 0.0  4.0   8.0  12.0
 1.0  5.0   9.0  13.0
 2.0  6.0  10.0  14.0
 3.0  7.0  11.0  15.0
  • 1次元配列に戻す
julia> vec(c)
16-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
 11.0
 12.0
 13.0
 14.0
 15.0
  • 行数自動で形状の変更
  • 列数自動で形状の変更
julia> b = collect(0.:3.)
4-element Array{Float64,1}:
 0.0
 1.0
 2.0
 3.0

julia> reshape(b, :, 1)
4×1 Array{Float64,2}:
 0.0
 1.0
 2.0
 3.0

julia> reshape(b, 1, :)
1×4 Array{Float64,2}:
 0.0  1.0  2.0  3.0

Juliaでnp.newaxisにあたるものはわかりませんでした。

その他の配列の操作

いろいろな配列の作成

  • 要素が全て0である配列の作成
julia> a = zeros(3, 4)
3×4 Array{Float64,2}:
 0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0
  • 要素が全て1である配列の作成
julia> b = ones(2, 2)
2×2 Array{Float64,2}:
 1.0  1.0
 1.0  1.0
  • 任意の要素を持つ配列の作成

np.emptyにあたるJuliaの関数は見当たらず・・・。
@tenfu2tea さんにご教示いただきました!
np.emptyにあたるJuliaの関数はBase.similar(Storagetype, axes) ということです。
https://docs.julialang.org/en/v1.0/base/arrays/#Base.similar

マニュアル読みましたが引数の指定が難しいですね・・・。similarなので似ているものを作ると言うことでしょうか。
本に近い形で作ろうとして下記のようになりました。

julia> similar(1:10, Float64, 2, 5)
2×5 Array{Float64,2}:
 2.21031e-314  4.94066e-324  2.21031e-314  4.94066e-323  2.47033e-323
 2.21031e-314  2.21031e-314  2.21031e-314  5.92879e-323  2.19521e-314
  • 等差数列を要素として持つ配列の作成

linspaceはないみたいなので、 rangeで指定するようです。
こちらも、@tenfu2tea さんにご教示いただきました!
LinRangeで指定するとのことです。
https://docs.julialang.org/en/v1.0/base/collections/#Base.LinRange

rangeで指定した方法とLinRangeで指定した方法を載せておきます。

  • range
julia> collect(range(0., stop = 1., length = 10))
10-element Array{Float64,1}:
 0.0               
 0.1111111111111111
 0.2222222222222222
 0.3333333333333333
 0.4444444444444444
 0.5555555555555556
 0.6666666666666666
 0.7777777777777778
 0.8888888888888888
 1.0 
  • LinRange
julia> collect(LinRange(0., 1., 10))
10-element Array{Float64,1}:
 0.0
 0.1111111111111111
 0.2222222222222222
 0.3333333333333333
 0.4444444444444444
 0.5555555555555556
 0.6666666666666666
 0.7777777777777778
 0.8888888888888888
 1.0

行列の連結

いろいろな行列の連結

  • 2次元配列を2つ用意
julia> a = [0 1 2; 3 4 5]
2×3 Array{Int64,2}:
 0  1  2
 3  4  5

julia> b = [6 7 8; 9 10 11]
2×3 Array{Int64,2}:
 6   7   8
 9  10  11
  • 縦方向に連結
julia> vcat(a, b)
4×3 Array{Int64,2}:
 0   1   2
 3   4   5
 6   7   8
 9  10  11
  • 横方向に連結
julia> hcat(a, b)
2×6 Array{Int64,2}:
 0  1  2  6   7   8
 3  4  5  9  10  11
  • さらに1次元配列を2つ用意
julia> c = collect(0:2)
3-element Array{Int64,1}:
 0
 1
 2

julia> d = collect(3:5)
3-element Array{Int64,1}:
 3
 4
 5
  • 縦方向に連結と横方向に連結
julia> vcat(c, d)
6-element Array{Int64,1}:
 0
 1
 2
 3
 4
 5

julia> hcat(c, d)
3×2 Array{Int64,2}:
 0  3
 1  4
 2  5
  • 形状が合わないとエラー
julia> vcat(a, c)
ERROR: ArgumentError: number of columns of each array must match (got (3, 1))
Stacktrace:
 [1] _typed_vcat(::Type{Int64}, ::Tuple{Array{Int64,2},Array{Int64,1}}) at ./abstractarray.jl:1283
 [2] typed_vcat at ./abstractarray.jl:1297 [inlined]
 [3] vcat(::Array{Int64,2}, ::Array{Int64,1}) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/SparseArrays/src/sparsevector.jl:1065
 [4] top-level scope at none:0
  • 2次元配列に変換してから連結
julia> vcat(a, reshape(c, 1, :))
3×3 Array{Int64,2}:
 0  1  2
 3  4  5
 0  1  2
1
1
2

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
1
1