Pandas(Python)と DataFrames(Julia)を Featherフォーマット で連係してみた【 Python目線 】


■ 概 要

  • こちらの続編になります。

  • 前編では、Pandas の DataFrame を引数渡しで処理する方法を説明しましたが、Julia側では辞書で処理していました。
  • Julia には PythonのPandas にあたる DataFrames.jl があり、どうせやるなら、Pandas(Python)と DataFrames(Julia)の間で DataFrame連係 させてみようと思い、今回やってみました。
  • DataFrame連係には、Featherというデータフォーマットを使用しました。Featherは、DataFrameを忠実に シリアライズ および デシリアライズ するように設計され、ディスクへの読み書きも効率化されており、データ分析言語間でのデータ共有に向いたデータフォーマットです。

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

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

pip install julia # Juliaとの連携

◇ Julia側:PyCallDataFrames.jlFeather のインストール

using Pkg; Pkg.add("PyCall") # Pythonとの連携
using Pkg; Pkg.add("DataFrames") # Julia版のPandas
using Pkg; Pkg.add("Feather") # Feather・DataFrame間の変換

■ コード

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

# Juliaプログラムからインスタンス生成
call_julia.include("call_julia.jl")

# データ型変換用のデコレータ DataFrame(pandas) <-> feather
def df2feather(func):
    def wrapper(in_df):
        in_df.to_feather("in.feather", version=1) # dataframe -> feather
        func("in.feather")                        # feather -> func
        out_df = pd.read_feather("out.feather")   # feather -> dataframe 
        return out_df
    return wrapper

# 引数がデータフレーム(featherファィル経由)
@df2feather
def calc_bmi(in_feather_file: str):
    return call_julia.calc_bmi(in_feather_file)

call_julia.jl 【Julia】

call_julia.jl
using DataFrames # using Pkg; Pkg.add("DataFrames")
using Feather    # using Pkg; Pkg.add("Feather")

# 引数がデータフレーム(featherファィル経由)
function calc_bmi(in_feather_file::String)
    dfs = Feather.read(in_feather_file) # feather -> dataframe

    dfs.bmi = dfs.weight ./ dfs.height .^ 2

    dfs.msg = ["普通" for r in 1:size(dfs, 1)]
    for row in eachrow(dfs)
        if row.bmi >= 25
            row.msg = "肥満"
        elseif row.bmi < 18.5
            row.msg = "低体重"
        end
    end

    Feather.write("out.feather", dfs) # dataframe -> feather
end

■ 使い方(実行画面)

  • 実行ファイル(.ipynb, .py)は、call_julia.pycall_julia.jl同じフォルダに置いて下さい。
  • データ連携用のFeatherファイル(in.feather,out.feather)も同じフォルダに出力します。

■ 注意点

  • Featherフォーマットで保存するときは、DataFrame の Index が デフォルト(0, 1,…)以外だとエラーになります。Index がデフォルトでない場合、.reset_index(drop=True) などで Index をリセットして下さい。
  • また、Featherフォーマットは、重複したカラム名や文字列以外のカラム名をサポートしていませんので、カラム名には注意して下さい。
  • Featherフォーマットのヴァージョンは、Ver.2が広く使われていますが、Julia側の Feather.jl がVer.2に対応していない為、Ver.1で連係しました。(2021.12.05現在)

■ 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上で動きます。