Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8901

Python for .NETを使ってPandas DataFrame から System.Data.DataTableへ変換する

$
0
0

Pythonと.NETの表データ交換

そもそもPython -> .NETでデータフレームを交換する場合、.NET側はDataTableという標準ライブラリのクラスがあるので、それが適しています。決してPandasやdplyrのような高機能なデータ処理能力は無いのですが、とりあえずマッピングすることができます。
BayesServerでPythonからも呼びたい場合は、以下にあるようにJPypeを使ったJavaライブラリへのアクセスを推奨されているようです。

Setup Python

一方で、pythonnetでもいいよ、と一言書いてあり、何で.NETネイティブなのに、Javaラッパーを通さないといけないのかよくわからないので、そちらで行くことにしました。RのラッパーもJavaラッパーを通します。これだと、APIリファレンスを2種類見ないといけない羽目になります。(どっちみち.NETライブラリに改造を加えて、再ラップするので)
最初からPythonにしておけば良かった。。。

pythonnet

pythonnet はPython for .NETと呼ばれる、Pythonから.NETのアクセスライブラリです。
http://pythonnet.github.io/
Pythonから.NETを呼び出す場合、.NETからPythonを呼び出す場合の双方で使えますね。

Python + .NETですと、IronPythonを思い出す人もいるのでしょうけども、そちらは.NET上で動くCLI言語です。これだと、データサイエンスなどで定評のあるライブラリも対応は限られます。というかnumpyが動きません。

pythonnetは言語間の接続を行うだけなので、両者の良いところを残したまま使えます。最新の.NET Coreなどにも対応します。
感覚的に言うと、

  • Pythonから、.NETのライブラリを using ではなく importで使える。
importclrclr.AddReference("System.Windows.Forms")fromSystem.Windows.FormsimportForm

import clrというのが趣があります。

  • .NETから、Pythonのライブラリを .NET 上でimportできる
dynamicnp=Py.Import("numpy");varx=np.cos(np.pi*2);

こっち方向は、 @hogegexさんの記事があります。

.NET (C#)からpythonを呼び出す

用途としては、Pythonから.NET独自のライブラリ(ビジネス系など)を呼び出したり、.NETから数値演算のタスクを投げたりなどが考えられます。Python上で.NETのGUIライブラリを使って、アプリを作れるのは中々良さそうですね。
ただ、私の用途はあくまでBayesServerのライブラリをPythonから呼ぶだけなので、以下のことができれば、おおむね完了です。

Python DataFrame -> .NET DataTable変換

BayesServerのリファレンスにはヘルパークラスとして、jpype1を使ったデータフレームのマッピングヘルパー関数が用意されています。

Pandas DataFrame helper functions

おそらく、jpype1を使った変換は癖があるので、こういったものを用意してくれていると思うのですが、pythonnetだともっとストレートに書けます。
ほぼ、コピペで.NET向けに書き直してみました。

# %%
importnumpyasnpimportpandasaspdimportclrfromSystem.Dataimport*# %%
def_to_net_class(data_type):"""
    Converts numpy data type to equivalent .NET class
    :param data_type: the numpy data type
    :return: The Net Class
    """ifdata_type==np.int32:returnclr.GetClrType(Int32)ifdata_type==np.int64:returnclr.GetClrType(Int64)ifdata_type==np.float32:returnclr.GetClrType(Single)ifdata_type==np.float64:returnclr.GetClrType(Double)ifdata_type==np.bool:returnclr.GetClrType(Boolean)ifdata_type==np.object:returnclr.GetClrType(Object)raiseValueError('dtype [{}] not currently supported'.format(data_type))# %%
defto_data_table(df):data_table=DataTable()forname,data_typeindf.dtypes.iteritems():net_class=_to_net_class(data_type)data_table.Columns.Add(str(name),net_class)forindex,rowindf.iterrows():xs=[Noneifpd.isnull(x)elsexforxinrow]data_table.Rows.Add(xs)returndata_table

これで、pandasのデータをするっと.NETライブラリに持ち込めるので、いわゆるExcel表のようなGUIや、データベースとの交換も楽になるかもです。
clr.GetClrType()というのがtypeof(やObject.GetType())の代わりみたいなものだと思ってください。


Viewing all articles
Browse latest Browse all 8901

Trending Articles