C# on Jupyter からの Numpy.NET 利用

Jupyter から C# で Numpy.NET ライブラリを利用できないかと思い、

#r "nuget: Numpy, 3.7.1.25"
using Numpy;

と記述するも、結論としては NG。このようなランタイムエラーが出る。

System.DllNotFoundException: Unable to load shared library 'python37' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libpython37: cannot open shared object file: No such file or directory
   at Python.Runtime.Runtime.Py_IsInitialized()
   at Python.Runtime.Runtime.Initialize(Boolean initSigs)
   at Python.Runtime.PythonEngine.Initialize(IEnumerable`1 args, Boolean setSysArgv, Boolean initSigs)
   at Python.Runtime.PythonEngine.Initialize(Boolean setSysArgv, Boolean initSigs)
   at Python.Runtime.PythonEngine.Initialize()
   at Numpy.np.InstallAndImport(Boolean force)
...


環境は、WSL2, Ubuntu 20.04LTS, Docker (tensorflow/tensorlow-latest-py3-jupter) イメージ, Jupyter Lab, Python3.6, .NET Interactive, dotnet-sdk-5.0 (ver. 5.0.302)。エラーを克服すべく試行錯誤すること半日。apt-get による Python 3.7 の追加インストール、.NET SDK 5.0.202 の追加インストール、python37.dll の追加配置、環境変数追加等々、エラーから推測されることを試すもすべてダメ。.NET Interactive ではなく Windows 上の Visual Studioコンパイルすると OK。

調べていくと Numpy は Numpy → Python.Included → Python.Deployment → pythonnet_netstandard_py37_win というパッケージ依存があり、この pythonnet_netstandard_py37_winC# から Python につなぐブリッジなのだが、その解説には

Python and CLR (.NET and Mono) cross-platform language interop. Compiled against .NetStandard 2.0 and CPython 3.7 (win64)

とある! Python and CLR (.NET and Mono) cross-platform language interop なのに、繋ぐ先として CPython 3.7 (win64) を想定してコンパイルしてあるだと!

クロスプラットフォーム .NET 5 のおかげで Windows でも Ubuntu でも PythonC# が (ビルド後 dll でもあっても) 使える write once, run anywhere 状態なのに、ブリッジ先が win64Python パッケージであるため、Jupyter (= Ubuntu) 上で記述した C# から接続できない … それは cross-language ではあっても cross-platform ではないのではないか ...


代わりに NumSharp ライブラリは使える。

#r "nuget: NumSharp, 0.30.0"
using NumSharp;

var x = ((NDArray) new double[] { 1, 2, 3, 4 }).reshape(2, 2);
var y = ((NDArray) new double[] { 4, 3, 2, 1 }).reshape(2, 2);

Console.WriteLine(x.dot(y).ToString()); // 行列の積
Console.WriteLine((x * y).ToString());  // アダマール積