PyCallを触ってみる

こんにちは、金子です。
普段はRubyを書いたりしています。

Rubyのコミッターであるmrknさんの新作gemである PyCall で遊んでみました。

作者のmrknさんによる資料は こちら

各種versionは以下のとおりです。

・Ruby: 2.4.0
・Python: 3.6.0
・PyCall: 009b2c6

現時点ではmasterを使うのがいいと思うので、git cloneしてきます。

$ git clone git@github.com:mrkn/pycall.git

コンソールを立ち上げます。

$ bundle install --path vendor/bundle
$ bundle console

 

pandasを呼び出す

さっそくpandasを使ってみましょう。
pythonのimportを行うために必要なモジュールをrequireし、includeします。

require "pycall/import"
include PyCall::Import
pyimport "pandas", as: :pd
# => :pd

準備ができたので、IRISデータを読みます。

df = pd.read_csv.("IRIS.csv", header: nil)
# =>       0         1    2         3    4         5    6         7          8
0   5.1  0.222222  3.5  0.625000  1.4  0.067797  0.2  0.041667     setosa
1   4.9  0.166667  3.0  0.416667  1.4  0.067797  0.2  0.041667     setosa
2   4.7  0.111111  3.2  0.500000  1.3  0.050847  0.2  0.041667     setosa
3   4.6  0.083333  3.1  0.458333  1.5  0.084746  0.2  0.041667     setosa
4   5.0  0.194444  3.6  0.666667  1.4  0.067797  0.2  0.041667     setosa
5   5.4  0.305556  3.9  0.791667  1.7  0.118644  0.4  0.125000     setosa
...

df.head.(3)
# =>      0         1    2         3    4         5    6         7       8
0  5.1  0.222222  3.5  0.625000  1.4  0.067797  0.2  0.041667  setosa
1  4.9  0.166667  3.0  0.416667  1.4  0.067797  0.2  0.041667  setosa
2  4.7  0.111111  3.2  0.500000  1.3  0.050847  0.2  0.041667  setosa

よしよし、動く。
 

扱えるPythonの関数を増やす

では、PyCallを編集して、扱えるPythonの関数を増やしましょう。
まず、Pythonのドキュメントを眺めます
今回は、Function Objectsにしましょう。モジュール名を取得するPyFunction_GetModuleと、引数のデフォルト値を取得するPyFunction_GetDefaultsを使いたいとします。

PyCall::LibPythonに関数を追加します。どちらの関数もPyObjectへのポインタをとり、PyObjectへのポインタを返すので、以下のように定義します。

     attach_function :PyModule_GetDict, [PyObject.by_ref], PyObject.by_ref

+    # Function
+
+    attach_function :PyFunction_GetModule, [PyObject.by_ref], PyObject.by_ref
+    attach_function :PyFunction_GetDefaults, [PyObject.by_ref], PyObject.by_ref
+
     # Import

     attach_function :PyImport_ImportModule, [:string], PyObject.by_ref

bundle consoleで再度、コンソールを立ち上げます。

require "pycall/import"
include PyCall::Import
pyimport "pandas", as: :pd

fun = pd.read_csv
# => <function _make_parser_function.<locals>.parser_f at 0x112e74378>
PyCall::LibPython.PyFunction_GetModule fun
# => 'pandas.io.parsers'
PyCall::LibPython.PyFunction_GetDefaults fun
# => (',', None, 'infer', None, None, None, False, None, True, None, None, None, None, None, False, None, None, None, True, True, False, True, False, False, False, None, False, False, None, 'infer', None, b'.', None, '"', 0, None, None, None, None, False, True, True, 0, 0, True, False, False, False, False, True, None, False, None)

はい、無事に呼び出せました。
たのしーい。
 

最後に

マネーフォワードでは、プログラミングが気になって夜も眠れないエンジニアを募集しています。
ご応募お待ちしています。

【採用サイト】
マネーフォワード採用サイト
Wantedly | マネーフォワード

【プロダクト一覧】
自動家計簿・資産管理サービス『マネーフォワード』
Web
iPhone,iPad
Android

ビジネス向けクラウドサービス『MFクラウドシリーズ』
会計ソフト『MFクラウド会計』
確定申告ソフト『MFクラウド確定申告』
請求書管理ソフト『MFクラウド請求書』
給与計算ソフト『MFクラウド給与』
経費精算ソフト『MFクラウド経費』
入金消込ソフト『MFクラウド消込』
マイナンバー管理ソフト『MFクラウドマイナンバー』
資金調達サービス『MFクラウドファイナンス』

メディア
くらしの経済メディア『MONEY PLUS』

Pocket