74
Help us understand the problem. What are the problem?

posted at

updated at

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

■ 投稿理由(動機)

  • 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.pycall_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連係

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
74
Help us understand the problem. What are the problem?