無需安裝Python,就能夠在.NET裏調用Python庫

Pythonnet這個屌爆的項目的出現,使得咱們能夠用一種新的方式,讓C#能夠和Python之間進行互操做。可是它的設置和部署可能有點問題,真的是這樣嗎?python

本文我會介紹Python.Included這個項目,它不但優雅的解決了這個問題,而且讓.NET開發者能夠輕鬆愉快的讓.NET與Python進行互操做。做爲概念的證實,我將使用Numpy.Net進行展現,它是一個.NET標準庫,它爲Python的Numpy提供了一個強類型API,而且使用它並不須要在Windows上安裝Python。數組

無需安裝Python,就能夠在.NET裏調用Python庫


開發人員從Numpy.NET的強類型API中獲益,與動態API不一樣,後者支持Visual Studio的IntelliSense功能,能夠顯示原始的Numpy文檔。bash

問題是什麼?

每一個人可能都安裝了不一樣版本的Python,有一些人用Python 2.7,其餘一些人用Python 3.5,3.6甚至3.7。當你使用pythonnet的時候,針對Python的每一個小版本,它必須使用不一樣的配置進行編譯,並且該版本的Python必須安裝,這樣代碼才能夠運行。因此若是你在團隊裏工做,每一個人就必須配置徹底相同的Python環境。但拿咱們的SciSharp團隊來講,狀況就已經不是這樣的了。若是你想部署你的.NET應用,你首先必須部署Python,從開發人員角度來說,這很鬧心。機器學習

然而,若是你正在搞機器學習和人工智能,儘管微軟和SciSharp都付出了很大努力,但目前你仍是沒法徹底避免Python的使用。若是你看一下正在使用pythonnet的項目的列表,你會發現不少AI領域的公司當前都在使用.NET與Python進行鏈接。函數

Python.Included 前來救援

若是你能夠很簡單的引用一個Nuget包,並在無需手動修改的狀況下,一切都會自動的配置好,假如能夠達到這種程度,你會感受怎麼樣?這就是我建立Python.Included的願景,Python.Included能夠把packages python-3.7.3-embed-amd64.zip包含在它的程序集裏,這這樣就容許你能夠經過Nuget來有效的引用Python了。爲了證實它能正常工做,並能夠快速提供全部的NumSharp中仍然缺乏的Numpy功能,我建立了基於Python.Included的Numpy.NET這個項目。性能

概念驗證:Numpy.NET

Numpy.NET爲Numpy提供了強類型的包裝函數,這意味着您徹底不須要使用dynamic關鍵字,但這部分我會在另外一篇文章中深刻討論。今天的重點是介紹 Numpy.NET 如何使用 Python.Included 來按需自動部署Python和Numpy以便對它們進行調用。學習

這是Numpy將在幕後實際執行的設置代碼。這些都不須要你來操做。一旦你使用了它的一個函數:測試

var a = np.array(new [,] {{1, 2}, {3, 4}});,
複製代碼

Numpy.dll 就會設置好嵌入的Python發行版,而它是從你本機home目錄裏的程序集裏解壓縮出來的(若是還沒安裝過的話)。人工智能

var installer = new Python.Included.Installer();
installer.SetupPython(force:false).Wait();
複製代碼

下一步(若是在以前的運行中還沒完成)它將解壓縮 numpy pip wheel,而numpy pip wheel 是做爲嵌入的資源打包到了Numpy.dll裏的並其安裝到了Python安裝文件裏。spa

installer.InstallWheel(typeof(NumPy).Assembly, "numpy-1.16.3-cp37-cp37m-win_amd64.whl").Wait();
複製代碼

最後,pythonnet運行時被初始化了,Numpy也被導入進來了,可供後續使用。

PythonEngine.Initialize();
Py.Import("numpy");
複製代碼

這些都是在幕後發生的,使用Numpy.dll的用戶根本不用擔憂本地的Python安裝。事實上,即便您已安裝了任何版本的Python也無所謂。

性能注意事項

你們都知道pythonnet比較慢,所以您可能會問本身,使用pythonnet將Python庫與.NET接在一塊兒是否真的是一個好主意。一如既往,這要看狀況而定。

個人測試結果代表,與直接從Python調用Numpy相比,使用.net調用numpy的開銷大約是它的4倍。須要澄清一下,這並不意味着Numpy.NET比python中的numpy慢四倍,這僅僅意味着經過pythonnet調用Numpy會有額外的開銷。固然了,因爲Numpy.NET調用的是Numpy,Numpy函數自己的執行時間是徹底相同的。

開銷是不是一個問題徹底取決於實際用例。若是您在一個嵌套循環中不斷的在CLR和Python之間來回切換,那就可能會遇到問題。但大多數Python庫的設計都都是爲了提升效率,避免數據循環。Numpy容許您只使用一個調用就能夠對數百萬的數組元素進行操做。Pytorch和Tensorflow容許您徹底在GPU上執行操做。所以,若是正確使用,與處理大量數據時操做的執行時間相比,互操做開銷能夠忽略不計。

路線圖

我知道如今有不少把Numpy移植到.NET上的方案和項目,例如使用IronPython。可是IronPython項目仍然只支持Python 2.7,並且項目進展很是緩慢。這就致使了依賴於python 3的庫不能經過IronPython來得到和使用,並且這種狀況在近期也不會有什麼改變。

個人重點是經過pythonnet爲.NET提供更多的機器學習和人工智能庫。SciSharp團隊也在討論如何研發出一個更快版本的pythonnet,從而避免使用天性緩慢的DynamicObject。

請嘗試一下Numpy.NET,並讓我知道它爲你作了什麼而且作的如何。若是有任何意見或建議,我將不勝感激,我但願個人工做可以幫助.NET機器學習社區成長和繁榮。

相關文章
相關標籤/搜索