python与matlab混合编程_python 与 matlab 混编
Matlab的官方文檔中介紹了 Matlab 與其余編程語言之間的引擎接口,其中包括對于 Python 開放的引擎 API,可參考官方教程,其中包括引擎安裝,基本使用,以及Python與Matlab之間的數(shù)據(jù)類型轉(zhuǎn)換及交互。
在 Windows 系統(tǒng)中:(可能需要管理員權(quán)限運(yùn)行)
cd "matlabroot\extern\engines\python"
python setup.py install
在 Mac 或 Linux 系統(tǒng)中:
cd "matlabroot/extern/engines/python"
python setup.py install
基礎(chǔ)用法
下面介紹數(shù)組的基本使用,其基本使用方法與 numpy 類似,但是 reshape() 函數(shù)略有不同,
import matlab
int_8 = matlab.int8([1, 2, 3, 4, 5, 6])
print(int_8) # [[1, 2, 3, 4, 5, 6]]
print(int_8.size) # (1, 6)
int_8.reshape((2, 3)) # reshape function is different from numpy
print(int_8) # [[1, 3, 5], [2, 4, 6]]
double = matlab.double([[1, 2, 3], [4, 5, 6]])
print(double) # [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
print(double[0]) # [1.0, 2.0, 3.0]
print(double[1][2]) # 6.0
對于數(shù)組的切片,Matlab 的 array 與 Python 的 list 也有所不同,官網(wǎng)給出的解釋在于,Matlab 數(shù)組切片返回的是一個(gè)視圖,而不是像 Python 中返回一個(gè)淺拷貝。
# Slice array
py = [[1, 2, 3], [4, 5, 6]]
mt = matlab.int32([[1, 2, 3], [4, 5, 6]])
py[0] = py[0][::-1]
mt[0] = mt[0][::-1]
# Slicing a Matlab array returns a view instead of a shallow copy
print(py) # [[3, 2, 1], [4, 5, 6]]
print(mt) # [[3, 2, 3], [4, 5, 6]]
Python的擴(kuò)展接口 中介紹:
Python 還可以通過引擎完成對 Matlab 的一些基本操作與控制。以下代碼需要在終端運(yùn)行:
import matlab.engine
eng = matlab.engine.start_matlab()
print(eng.sqrt(4.)) # 2.0
eng.plot(matlab.int32([1, 2, 3, 4]), matlab.int32([1, 2, 3, 4]))
eng.eval("hold on", nargout=0)
eng.eval("plot([4, 3, 2, 1], [1, 2, 3, 4])", nargout=0)
eng.eval("x = 3", nargout=0)
eng.eval("y = 41", nargout=0)
eng.eval("z = [213, 123]", nargout=0)
print(eng.workspace)
print(eng.workspace['x'], eng.workspace['z'])
"""
Name Size Bytes Class Attributes
x 1x1 8 double
y 1x1 8 double
z 1x2 16 double
3.0 [[213.0,123.0]]
"""
input("Press Enter to exit.")
eng.quit()
Python-Matlab調(diào)用(call) m 文件
定義入口函數(shù) callentry,接收兩個(gè)參數(shù),隨后對兩個(gè)參數(shù)分別在內(nèi)部進(jìn)行加和乘操作,再調(diào)用外部另一個(gè) m 文件的 callsub 函數(shù)進(jìn)行相減操作,將返回的結(jié)果保存在數(shù)組r中返回。
callentry.m 代碼:
function [x, y, z] = callentry(a, b);
x = add(a, b)
y = mul(a, b)
z = callsub(a, b)
end
function l = mul(m, n);
l=m*n;
end
function l = add(m, n);
l=m+n;
end
callsub.m 代碼
function r = callsub(a, b);
r = a-b;
end
在 Python 中,運(yùn)行如下代碼
import matlab.engine
eng = matlab.engine.start_matlab()
print(eng.callentry(7.7, 2.1, nargout=3))
eng.quit()
Note: 值得注意的是,此處需要設(shè)置 nargout 參數(shù),當(dāng)未設(shè)置時(shí)默認(rèn)為 1,即默認(rèn)只返回 1 個(gè)參數(shù),當(dāng)知道 Matlab 返回參數(shù)的數(shù)量時(shí),通過nargout 進(jìn)行設(shè)置來獲取所有需要的參數(shù)。無參數(shù)返回時(shí)請?jiān)O(shè)為 0。
在第一次運(yùn)行生成實(shí)例時(shí)會較慢,因?yàn)樾枰獑?dòng) Matlab 引擎,最終得到輸出如下,可以看到,Matlab 的 console 界面顯示的結(jié)果在 Python 中也會輸出,最后得到的結(jié)果是列表形式的 Python 數(shù)據(jù)。
x =
9.8000
y =
16.1700
z =
5.6000
r =
9.8000 16.1700 5.6000
(9.8, 16.17, 5.6)
MATLAB 中 調(diào)用 Python
只要正確安裝對應(yīng)的 matlab 和 python,一般就可以使用了(不需要手動(dòng)設(shè)置路徑)。
matlab 官方教程:從 MATLAB 調(diào)用 Python
matlab 把所有參數(shù)輸出到一個(gè)文件里,然后用 system 命令調(diào) python 腳本。python 腳本讀文件做計(jì)算結(jié)果再寫文件。最后 matlab 再讀文件得到結(jié)果。假設(shè) python 腳本的用法是:
python xxx.py in.txt out.txt
則 matlab 調(diào)用的命令:
[status, cmdout] = system('python xxx.py in.txt out.txt')
Matlab 的 system 函數(shù)用來向操作系統(tǒng)發(fā)送一條指令,并得到控制臺的輸出,可以直接將控制臺的輸出在 Command Window 打印出來,或者保存在變量中。 與 system 類似的還有 dos 函數(shù)和 unix 函數(shù),我覺得它們都是對 system 函數(shù)的一種包裝,而 Matlab 的 system 函數(shù)也許是對 C 的庫函數(shù)system 的包裝。
先編寫一個(gè)調(diào)用 Python 腳本的 matlab 程序即 python.m
function [result status] = python(varargin)
% call python
%命令字符串
cmdString='python';
for i = 1:nargin
thisArg = varargin{i};
if isempty(thisArg) | ~ischar(thisArg)
error(['All input arguments must be valid strings.']);
elseif exist(thisArg)==2
%這是一個(gè)在Matlab路徑中的可用的文件
if isempty(dir(thisArg))
%得到完整路徑
thisArg = which(thisArg);
end
elseif i==1
% 第一個(gè)參數(shù)是Python文件 - 必須是一個(gè)可用的文件
error(['Unable to find Python file: ', thisArg]);
end
% 如果thisArg中有空格,就用雙引號把它括起來
if any(thisArg == ' ')
thisArg = ['"''"', thisArg, '"'];
end
% 將thisArg加在cmdString后面
cmdString = [cmdString, ' ', thisArg]
end
%發(fā)送命令
[status,result]=system(cmdString);
end
就可以用這個(gè)函數(shù)調(diào)用 python 腳本了。 下面就來個(gè)調(diào)用 python 腳本 matlab_readlines.py (保存在 matlab 當(dāng)前目錄)的例子:
import sys
def readLines(fname):
try:
f=open(fname,'r')
li=f.read().splitlines()
cell='{'+repr(li)[1:-1]+'}'
f.close()
print cell
except IOError:
print "Can't open file "+fname
if '__main__'==__name__:
if len(sys.argv)<2:
print 'No file specified.'
sys.exit()
else:
readLines(sys.argv[1])
這個(gè)腳本用來讀取一個(gè)文本文件,并生成 Matlab 風(fēng)格的 cell 數(shù)組的定義字符串,每個(gè)單元為文本的一行。 放了一個(gè)測試用的文本文件 test.txt 在Matlab 的 Current Directory 中,內(nèi)容如下:
This is test.txt
It can help you test python.m
and matlab_readlines.py
測試:
在 Matlab 的 Command Window 中輸入:
str = python('matlab_readlines.py','test.txt');
eval(['c = ' str])
celldisp(c)
下面我舉一個(gè) python 轉(zhuǎn) matlab 的例子:
HDF5 轉(zhuǎn) .mat
# 載入必備的庫和數(shù)據(jù)
import tables as tb
import scipy.io as sio
h5 = tb.open_file('E:/xdata/X.h5')
fm = h5.root.fashion_mnist # 獲取 fashion_mnist 數(shù)據(jù)
mdict = {
'testX':fm.testX[:].reshape((fm.testX.shape[0], -1)),
'trainX':fm.trainX[:].reshape((fm.trainX.shape[0], -1)),
'trainY':fm.trainY[:],
'testY':fm.testY[:],
}
sio.savemat('fashion_mnist', mdict) # 保存到本地 fashion_mnist.mat
總結(jié)
以上是生活随笔為你收集整理的python与matlab混合编程_python 与 matlab 混编的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消息称字节跳动成立新部门 Flow,发力
- 下一篇: python 画树 递归_python递