Data Science with Julia && Python (2) - NumpyもJulia環境下で使う

Juliaを使いはじめて良いなと思った所はPythonのライブラリが使えることです。当然ながら全く同じ事ができるわけではないですが、Data Scienceでよく使われるものがJulia上でもちょっと知ればできるのは大きいです。

今回はNumpy「も」Julia環境で使いながらJuliaで同様の結果を得る方法を検討してみます。

Julia上でPythonのライブラリを使うには前回書いたようにPyCallというパッケージが必要です。PyCallをインストールしていなければ

import Pkg; Pkg.add("PyCall")

とREPL上で入力してインストールします。早速PyCallを使いましょう

using PyCall

ではnumpyをインポートします。

julia> np = pyimport("numpy")

画像1

私の環境では新しくPython3.6環境をcondaで作成し(py36env)、そこのPATHを通しています。これでnumpyが使えるようになりました。3x3のArrayを作ってみましょう。

julia> arr_2d = np.array([[5,10,15],[20,25,30],[35,40,45]])

画像2

ここで30を選択しようとする場合Pythonならarr_2d[1][2]でしょうか。これはJulia環境下ではエラーとなります。Juliaは0-based indexではなく1-based indexですから30を選ぶ場合は

arr_2d[2,3] # 2nd row, 3rd column

となります。もし[[10,15], [25,30]]を得ようとするなら、PythonとJuliaでは

python> arr_2d[:2, 1:]
julia> arr_2d[1:2, 2:end]

です。Pythonでは最初の2は含みませんが、Juliaでは両方がinclusiveです。個人的にはJuliaの方がいろいろと直感的ですが、Juliaの場合Pythonの1:のように省略するとエラーがでますので、2:end(もしくは2:3)とする必要があります。

1から10の配列を作成する場合は以下のどちらでも構いません。

arr = np.arange(1,11)
arr = Array(1:10)

繰り返しますがJuliaは1-based indexなので1:10です。JuliaのArrayのほうがシンプルなのでJuliaで同様の事ができる場合はJuliaの方式を試していくのがこのシリーズです。

例えばelementが5以上を選択する場合は

python> arr[arr > 5]
julia> arr[arr .> 5]

>の前にあるドットはelementごとに計算することを明示しています。このドットを忘れるとエラーがでます。

python> a = np.arange(50).reshape(5,10)

画像6

Pythonだと5x10のArrayができます。ですがJulia環境下では.reshapeのようにMethodを書くようにするとエラーがでます。np.arange(50)はできるのですが、reshapeする場合は

julia> reshape(np.arange(50), (5,10))

とする必要があります。頭の中では以下のような結果を想像されたかもしれませんが・・・

画像4

実際に表示されるのは以下のようにコラムベースです。

画像5

Python(やC)はrowベースで表示するのですが、Julia(やFortrun, Matlab, R)はcolumnベースです。Columnベースの方がPerformanceが良いようでこうなっているのが分かりますが、慣れるまでは大変です。あえてPythonと同じ結果を出そうと思うならpermutedimsを使いますが、後述するLinearAlgebraというパッケージを使えばadjointという機能が使えます。

reshape(a,10,5)'

最後のシングルクォーテーションは間違いではなくadjointを使う印です。

画像12

numpyを利用したりJuliaを使って済むものなどは基本的に多いです

python> np.zeros(10)
julia> zeros(10)
python> np.ones(10)
julia> ones(10)
python> np.ones(10) * 5
python> np.zeros(10) + 5
julia> ones(10) * 5
julia> zeros(10) .+ 5

画像6

Juliaでする場合、要素ごとに計算する際にはドットが必ず必要なので慣れるまではnumpyを使うのもいいかもしれません。Python>と記しましたが上記すべてJulia上で同じ結果を出します。以下もそうです。

np.arange(10,51)
Array{Int}(10:50)
np.arange(10,51,2)
Array{Int}(10:2:50)

3x3 Matrixを0から8の数字を用いて作るなら

reshape(np.arange(9),(3,3))
reshape(0:8,3,3)

しばらくは.reshapeのようにオブジェクトのあとにMethodをつけない形に煩わさしさを感じるかもしれませんが、慣れればシンプルです。

3x3 Identity Matrixを作る場合はnumpyはシンプルでいいですね

np.eye(3)

Juliaだけでする場合はLinearAlgebraのパッケージが必要になります

using LinearAlgebra
Matrix{Float64}(I,3,3)

0から1の範囲でランダムな数字を出す際はJuliaの方がシンプルです

np.random.rand(1)
rand(1)
np.random.randn(25)
randn(25)

0.01から1まで均等に100等分された数字で10x10 Matrix作成する場合

reshape(np.linspace(0.01,1,100),(10,10))
reshape(0.01:0.01:1,(10,10))

0から1までに20等分された数字を出す場合

np.linspace(0,1,20)
LinRange(0,1,20)

どっちを使ってもいいですね

Juliaでも同様の結果を簡単にだせるのですが、numpyに慣れている場合はnumpyを使えばいいと思います。.reshape()や.shapeのようなMethodの形が使えないという点を気をつけて利用していきましょう。

画像7

1から25で5x5の配列を作成します。上記から[2, 7, 12]、もしくは一番下の行を取り出したい場合は

画像8

数字に関してはいろいろ書けると思いますが、直感的であるのはありがたいです。合計数を出す場合は

画像9

それぞれに列の合計を出す場合は

画像10

Pythonでは.sumそしてaxis=0が必要ですが、JuliaではsumはFunctionとして使い、axisの代わりにdimsです。このStandard deviationを出す場合

画像11

これを仮にPython環境下ですると、np.std(mat_j)ですが結果は7.211となります。これはNumpy.stdの標準が正規分布での最尤推定量をだすのに対し、JuliaではUnbiased estimateだからです。同様の結果はnp.std(mat_j, ddof=1)とすればでます。

np.std(mat_j) == std(mat_j, corrected=false) # unbiased estimator
OR
np.std(mat_j, ddof=1) == std(mat_j) # biased estimator

次回はData Scienceに必須のPandasです。

この記事が気に入ったらサポートをしてみませんか?