Pythonは特に統計処理や機械学習、数値計算などの科学技術計算に強みがありますが、その中心的基盤となっているモジュールはNumPyです。それに対してC#はオールマイティに使える言語ではありますが、Pythonのような科学技術計算のための共通基盤は用意されていません。そこで、ここではC#からNumPyを用いるためのライブラリであるNumpy.NETを導入して、C#からNumPyを使う方法を見ていきましょう。
Numpy.NETとは?
C#によるデータサイエンスや機械学習の環境を構築するオープンソースプロジェクトにSciSharpというものがあり、Numpy.NETはそのプロジェクトの一環として開発されています。同じくSciSharpによってPython.NETという「C# → Python」「Python → C#」の呼び出しを可能にするライブラリが開発されており、Numpy.NETでもそのバックエンドではPython.NETが用いられています。これを用いて本家のNumPyに類似したコードでC#から実際のPython NumPyの関数を実行することができるようになっています。
Numpy.NETを使えば強力な科学技術計算の共通基盤であるNumPyをC#のプロジェクトの中に組み込むことができます。また、NumPyのバイナリ形式で配列データ(ndarrayオブジェクト)を保存することもできるので、Pythonスクリプトで生成したNumPyのデータをC#のプログラムで用いることもできますし、その逆も可能です。SciSharpプロジェクトには機械学習ライブラリであるKerasやPyTorchをC#で用いるためのプロジェクトであるKeras.NETやTorch.NETもあり、これらの基盤としてもNumpy.NETが用いられています。
なお、同じSciSharpのプロジェクトでC#からNumPyを用いるためのライブラリとしてNumSharpというものもあります。Numpy.NETはバックエンドでは実際のPython NumPyの関数を用いて処理を行っているのに対して、NumSharpは100%ピュアなC#のライブラリであるという違いがあります。Numpy.NETでは本家のNumPyとの橋渡しをしているだけなので、NumPyのほとんどの関数がそのまま使え演算結果も全く同じになりますが、NumSharpではNumPyの代表的な関数しか移植されておらず、演算結果も厳密に全く同じとは限らないという違いがあります。
Numpy.NETのインストール
Visual StudioでC#環境を整えていればNuGetからワンクリックでNumpy.NETを導入することができます。
まずは、「ツール」→「NuGetパッケージマネージャー」→「ソリューションのNuGetパッケージの管理」からNuGetの管理画面を開きましょう。
続いて、「scisharp numpy」などのように入力してNumpy.NETを検索します。似たような名前のものがたくさんありますが、以下に表示している「Numpy」がNumpy.NETになります。
これを選択して希望するプロジェクトにインストールするだけで、Numpy.NETの使用準備は完了です。
なお、Numpy.NETはあくまでもPythonのNumPyへのラッパーなので、裏ではPythonのNumPyそのものが動いているのですが、上記のNuGetパッケージにはPython自体が含まれているので、特に意識せずに使うことができます。
Numpy.NETの基本的な使い方
Numpy.NETでは基本的にPythonのNumPyに準じた使い方ができるようになっています。Numpy.NETを使うためには、まずusing文を用いてNumpy名前空間への参照を加える必要があります。Numpy.NETでよく用いるメソッドはnpクラスに静的メソッドとして用意されています。また、C#では通常クラス名やメソッド名はパスカル記法が用いられますが、Numpy.NETではPythonのクラス名・メソッド名に合わせるために敢えてC#の標準のコーディング規則からは外れている部分もあります。
ndarrayを生成してみる
Python NumPyではリストからndarrayを生成するにはarray関数を用いますが、Numpy.NETでも同様のarray<T>メソッドが用意されています。例えば[1, 2, 3, 4, 5]を要素に持つndarrayをC#で生成してみましょう。
using System;
using Numpy;
class Program
{
static void Main(string[] args)
{
var m = np.array(new int[] { 1, 2, 3, 4, 5 });
Console.WriteLine(m);
}
}
[1 2 3 4 5]
8行目でNDarray<T>オブジェクトを生成して、それを9行目で表示しています。なお、型パラメーターは明らかなので省略しています。ここで生成したNDarray<T>オブジェクトはPython NumPyのndarrayと同様に扱うことができ、例えば次のように要素ごとの足し算を行うこともできます。
var m1 = np.array(new int[] { 1, 2, 3, 4, 5 });
var m2 = np.array(new int[] { 5, 4, 3, 2, 1 });
Console.WriteLine(m1 + m2);
[6 6 6 6 6]
ndarrayをファイルに出力する
生成したNDarray<T>オブジェクトは本家のNumPyと同様にsaveメソッドでnpy形式に保存することができます。
using Numpy;
class Program
{
static void Main(string[] args)
{
var m = np.array(new int[] { 1, 2, 3, 4, 5 });
var filepath = @"C:\BioTech-Lab\test.npy";
np.save(filepath, m);
}
}
ここで保存したtest.npyファイルを試しにPython上から開いてみましょう。
import numpy as np
filepath = r"C:\BioTech-Lab\test.npy"
m = np.load(filepath)
print(m)
[1 2 3 4 5]
Python上からも問題なく開くことが確認できました。これでC#で作成したndarrayをPythonスクリプトに渡せることが分かります。
ファイルからndarrayを読み込む
逆にndarrayのバイナリファイル(.npy)をNumpy.NETから読み込む場合は、loadメソッドを用います。これを用いて先ほど保存したtest.npyファイルを読み込んでみましょう。
using System;
using Numpy;
class Program
{
static void Main(string[] args)
{
var filepath = @"C:\BioTech-Lab\test.npy";
var m = np.load(filepath);
Console.WriteLine(m);
}
}
[1 2 3 4 5]
正しくNDarray<T>オブジェクトとして読み込めていることが分かりました。
コメント