58
74

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

遅いPythonの処理 は Julia にやらせよう

Last updated at Posted at 2021-11-22

■ 投稿理由(動機)

  • Python から Julia を呼び出す処理は、Julia のファイル名を指定して実行させるものがほとんどで、Python から Julia へ引数を渡して処理させる方法が見当たらなかったので投稿しました。
  • なお、Pandas の DataFrame も引数で渡せるので、適用範囲はかなり広がると思います。
  • Python の欠点である演算速度の遅さを、Julia でカバーできると思い記事にしました。
    下のグラフは私の非力PCで処理した結果で、Julia圧勝です。 Python:327秒 Julia:3.3秒
    image.png

■ ライブラリのインストール

◇ Python側:PyJulia のインストール

pip install julia # Juliaとの連携

◇ Julia側:PyCallJSON のインストール

using Pkg; Pkg.add("PyCall") # Pythonとの連携
using Pkg; Pkg.add("JSON") # JSONデータのパース(構文解析)

■ コード

call_julia.py 【Python】

call_julia.py
from julia import Julia # !pip install julia
Julia(compiled_modules = False) # PyJuliaの設定変更
from julia import Main as call_julia
import pandas as pd

# "call_julia.jl"を取り込み、call_juliaインスタンス を生成
call_julia.include("call_julia.jl")

# データ型変換用のデコレータ DataFrame(Python) <-> json(Julia)
def df2json(func):
    def wrapper(in_df):
        in_json = in_df.to_json(orient='records') # dataframe -> json
        out_json = func(in_json)                  # json -> func -> json
        out_df = pd.read_json(out_json)           # json -> dataframe 
        return out_df
    return wrapper

# 引数なし
def hello_world() -> str:
    return call_julia.hello_world()

# 引数あり
def fib(n: int) -> int:
    return call_julia.fib(n)

# 引数がデータフレーム  dataframe -> json 渡し
@df2json
def calc_df(in_json: str) -> str:
    return call_julia.calc_df(in_json)

call_julia.jl 【Julia】

call_julia.jl
using JSON # using Pkg; Pkg.add("JSON")

# 引数なし
function hello_world() # ハローワールド
    "Hello World"
end

# 引数あり
function fib(n) # フェボナッチ数列(再帰ヴァージョン)
    if n == 0
        return 0 
    elseif n < 3
        return 1
    end
    fib(n-1) + fib(n-2)
end

# 引数がデータフレーム  dataframe -> json 渡し
function calc_df(in_json)
    in_dic = JSON.parse(in_json)
    
    for dic in in_dic
        dic["join"] = string(dic["No"]) * dic["item"]
    end    
    
    JSON.json(in_dic)
end

■ 使い方(実行画面)

  • 実行ファイル(.ipynb, .py)は、call_julia.py,call_julia.jl と同じフォルダに置いて下さい。
    image.png

■ 特記事項(工夫した点)

  • call_julia.py の引数をデータフレームで渡す処理は、DataFrame を JSON に変換して Julia側 に渡しています。そして、Julia側 の処理結果も JSON から DataFrame へ変換して返しています。これら一連の処理は、**デコレータ(df2json)**を使って実装しました。

■ Python と Julia が動く環境の構築方法

  • 私の場合は、dockerhub から jupyter/datascience-notebook という docker image をプルして構築しました。参考までに docker run スクリプトはこんな感じです。
docker run -v D:\DS\temp\work:/home/jovyan/work -p 9998:8888 --name prj-env jupyter/datascience-notebook
  • なお、D:\DS\temp\work と 9998 と prj-env の箇所は、任意に決めていただいて結構です
    この環境では、Python と Julia だけでなく R も JupyterNotebook上で動きます。

(補足)DataFrames.jl との DataFrame連係

58
74
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
58
74

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?