解決python調用matlab時的一些常見問題
為什麼要用python調用matlab?
我自己的有些數據結構涉及到hash查找,在python中key是tuple形式,在matlab中支持hash查找的數據結構隻有containers.Map(),並不能支持cell作為key。
嘗試過把向量轉為string,但是num2str和str2mat的效率不高,containers.Map()的查找耗時也非常的長,所以隻好作罷。
後來發現可以用python通過matlab的API直接調用matlab的函數參與運算,朋友的經驗說矩陣運算都交給matlab來計算就很快瞭。
但是摸索過程中發現一些問題,在網絡上基本找不到,自己全靠摸索發現解決方式,寫在這裡,如果能給大傢帶來幫助,那就很好瞭。
配置python以調用matlab的API
python環境
這裡以py2.7和Spyder的anaconda為例。
通過mlab庫
這個包直接搜索到官網上下載即可。也可以嘗試pip,我已經忘瞭當時怎麼裝上的瞭。
裝好之後,使用示例如下:
from mlab.releases import latest_release as matlab import os path = os.getcwd() mat.path(mat.path(),path) # 添加當前腳本所在路徑到matlab的環境中 ......
所有的matlab(包括自定義函數)的可以通過matlab.xxxx()的方式調用。
mlab包的優點
matlab中的所有變量都是矩陣形式的,到python中會自動轉為numpy的array形式,非常方便。
mlab包的缺點
這是最大的BUG!那就是自定義函數在通過mlab在python中調用之後,就好像編譯隻讀瞭一樣,此後對.m文件的任何修改都不起作用,不管是重新啟動python的kernel、重新啟動spyder、重新import mlab、刪除.m文件重建同名函數.m文件,都行不通。刪除瞭.m文件,python報錯,除非重新命名一個新函數後調用,那麼這個新函數同樣面臨無法修改的問題。
除非重啟電腦。
因此我選擇瞭另一個方式,也是matlab官網介紹的方式。
通過matlab.engine
matlab官網的鏈接:MATLAB API for Python。
安裝過程:
1、在matlab安裝路徑中,找到”R2016b\extern\engines\python”,每個人安裝路徑不一樣,找到末尾一致路徑即可
2、這裡註意區分,通過anaconda prompt打開其命令行,依次執行:d: –>cd D:\Program Files\MATLAB\R2016b\extern\engines\python,即切換路徑到matlab的python的setup.py下
3、官方還給出瞭較全的安裝方案,跟著做就好:在非默認位置安裝用於 Python 的 MATLAB 引擎 API
4、安裝完成後,python中就可測試以下內容瞭:
#coding=utf-8 import matlab.engine from numpy import * if __name__ == '__main__': eng = matlab.engine.start_matlab() A = matlab.double([[1,2],[5,6]]) print(type(A),A.size,A) print(eng.eig(A)) eng.quit() pass
matlab.engine包的優點
這是matlab官方介紹的方法,不會出現mlab的那種問題,可以邊寫程序邊調試沒問題瞭。
matlab.engine包的缺點
使用的變量中有許多的matlab類,其中一些在spyder的Variable explorer中無法顯示,必須人為打印。
另外就是必須註意python變量類型和matlab變量類型的對應關系,matlab給出瞭一張表:Pass Data to MATLAB from Python。
我習慣上會把變量以list的方式 [1,2,3] 傳入到matlab的函數中,這樣matlab裡面實際認為是cell,調試中遇到瞭很多次,實際上如果隻傳數值到函數中,需要在python中將變量設置為 matlab.double([1,2,3]) 傳入才正常。
實用建議
matlab.double類型的變量,可以通過numpy.asarray方式轉為array類型的變量,方便在python中處理。
matlab中的函數返回到python中的值默認為1個,需要在函數中增加一個參數nargout=n,如果n與返回的個數不一致,python會報錯。
總結
官方介紹的matlab.engine更好用。
matlab負責處理矩陣計算,python用以解決hash查找的數據結構。
目前還在開發初期階段,並不知道數據在python和matlab之間的通信效率高不高。
第一次寫總結,主要是為瞭給自己總結用,避免以後發生同樣的錯誤。考慮到網絡上相關問題的中文介紹非常少,能找到的都是抄過來抄過去的基礎配置問題,我這裡分享出來,以期能夠幫助到其他朋友。
補充:python調用matlab問題解決小建議
軟件及python位數要一致
cmd進行build和install時需要管理員權限運行
多個版本的情況下,需要使用python、python2、python3進行python2 setpy.py build這樣
函數的參數一般需要matlab.double轉換或者參數賦值時直接改為double型
import matlab.engine eng = matlab.engine.start_matlab()
需要保證你的函數或腳本就在當前的工作路徑下,也就是說要把m文件放到python程序中去
matlab.double([44100]) matlab.double([[1.0,1.4142135623730951,1.7320508075688772,2.0,2.23606797749979]]) signal = eng.hanshu(matlab.double([44100]), matlab.double([3000]), matlab.double([5]))
默認情況下,API認為接收函數返回結果的參數有1個。
這會導致沒有返回值的函數在被調用時報錯:“Too many output arguments”或是多個返回值的情況下隻返回並得到第一個返回值
我們可以人為指定輸出參數為0個來避免這樣的錯誤。
eng.hanshu(canshu, nargout=2)
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- python調用matlab的方法詳解
- python數字圖像處理環境安裝與配置過程示例
- Python numpy和matlab的幾點差異介紹
- python matlab庫簡單用法講解
- python中NumPy的安裝與基本操作