NumPy for MATLAB users#
引言#
MATLAB® and NumPy have a lot in common, but NumPy was created to work with Python, not to be a MATLAB clone. This guide will help MATLAB users get started with NumPy.
Some key differences#
In MATLAB, the basic type, even for scalars, is a multidimensional array. Array assignments in MATLAB are stored as 2D arrays of double precision floating point numbers, unless you specify the number of dimensions and type. Operations on the 2D instances of these arrays are modeled on matrix operations in linear algebra. |
In NumPy, the basic type is a multidimensional |
MATLAB numbers indices from 1; |
NumPy, like Python, numbers indices from 0; |
MATLAB’s scripting language was created for linear algebra so the syntax for some array manipulations is more compact than NumPy’s. On the other hand, the API for adding GUIs and creating full-fledged applications is more or less an afterthought. |
NumPy is based on Python, a general-purpose language. The advantage to NumPy is access to Python libraries including: SciPy, Matplotlib, Pandas, OpenCV, and more. In addition, Python is often embedded as a scripting language in other software, allowing NumPy to be used there too. |
MATLAB array slicing uses pass-by-value semantics, with a lazy copy-on-write scheme to prevent creating copies until they are needed. Slicing operations copy parts of the array. |
NumPy array slicing uses pass-by-reference, that does not copy the arguments. Slicing operations are views into an array. |
Rough equivalents#
The table below gives rough equivalents for some common MATLAB expressions. These are similar expressions, not equivalents. For details, see the documentation.
In the table below, it is assumed that you have executed the following commands in Python
import numpy as np
from scipy import io, integrate, linalg, signal
from scipy.sparse.linalg import cg, eigs
Also assume below that if the Notes talk about “matrix” that the arguments are two-dimensional entities.
General purpose equivalents#
MATLAB |
NumPy |
备注 |
|---|---|---|
|
|
get help on the function func |
|
find out where func is defined |
|
|
|
print source for func (if not a native function) |
|
|
comment a line of code with the text |
for i=1:3
fprintf('%i\n',i)
end
|
for i in range(1, 4):
print(i)
|
use a for-loop to print the numbers 1, 2, and 3 using |
|
|
short-circuiting logical AND operator (Python native operator); scalar arguments only |
|
|
short-circuiting logical OR operator (Python native operator); scalar arguments only |
>> 4 == 4
ans = 1
>> 4 == 5
ans = 0
|
>>> 4 == 4
True
>>> 4 == 5
False
|
The boolean objects in Python are |
a=4
if a==4
fprintf('a = 4\n')
elseif a==5
fprintf('a = 5\n')
end
|
a = 4
if a == 4:
print('a = 4')
elif a == 5:
print('a = 5')
|
create an if-else statement to check if |
|
|
complex numbers |
|
|
distance from 1 to the next larger representable real number in double precision |
|
|
Load MATLAB variables saved to the file |
|
|
integrate an ODE with Runge-Kutta 4,5 |
|
|
integrate an ODE with BDF method |
Linear algebra equivalents#
MATLAB |
NumPy |
备注 |
|---|---|---|
|
|
number of dimensions of array |
|
|
number of elements of array |
|
|
“size” of array |
|
|
get the number of elements of the n-th dimension of array |
|
|
define a 2x3 2D array |
|
|
construct a matrix from blocks |
|
|
access last element in MATLAB vector (1xn or nx1) or 1D NumPy array |
|
|
access element in second row, fifth column in 2D array |
|
|
entire second row of 2D array |
|
|
first 5 rows of 2D array |
|
|
last 5 rows of 2D array |
|
|
The first through third rows and fifth through ninth columns of a 2D array, |
|
|
rows 2,4 and 5 and columns 1 and 3. This allows the matrix to be modified, and doesn’t require a regular slice. |
|
|
every other row of |
|
|
every other row of |
|
|
|
|
|
|
|
|
transpose of |
|
|
conjugate transpose of |
|
|
matrix multiply |
|
|
element-wise multiply |
|
|
element-wise divide |
|
|
element-wise exponentiation |
|
|
matrix whose i,jth element is (a_ij > 0.5). The MATLAB result is an array of logical values 0 and 1. The NumPy result is an array of the boolean values |
|
|
find the indices where ( |
|
|
extract the columns of |
|
|
extract the columns of |
|
|
|
|
|
|
|
|
set all values to the same scalar value |
|
|
NumPy assigns by reference |
|
|
NumPy slices are by reference |
|
|
turn array into vector (note that this forces a copy). To obtain the same data ordering as in MATLAB, use |
|
|
create an increasing vector (see note RANGES) |
|
|
create an increasing vector (see note RANGES) |
|
|
create a column vector |
|
|
3x4 two-dimensional array full of 64-bit floating point zeros |
|
|
3x4x5 three-dimensional array full of 64-bit floating point zeros |
|
|
3x4 two-dimensional array full of 64-bit floating point ones |
|
|
3x3 identity matrix |
|
|
returns a vector of the diagonal elements of 2D array, |
|
|
returns a square diagonal matrix whose nonzero values are the elements of vector, |
rng(42,'twister')
rand(3,4)
|
from numpy.random import default_rng
rng = default_rng(42)
rng.random((3, 4))
or older version: |
generate a random 3x4 array with default random number generator and seed = 42 |
|
|
4 equally spaced samples between 1 and 3, inclusive |
|
|
two 2D arrays: one of x values, the other of y values |
|
the best way to eval functions on a grid |
|
|
|
|
|
the best way to eval functions on a grid |
|
|
|
create m by n copies of |
|
|
concatenate columns of |
|
|
concatenate rows of |
|
|
maximum element of |
|
|
maximum element of each column of array |
|
|
maximum element of each row of array |
|
|
compares |
|
|
L2 norm of vector |
|
|
element-by-element AND operator (NumPy ufunc) See note LOGICOPS |
|
|
element-by-element OR operator (NumPy ufunc) See note LOGICOPS |
|
|
bitwise AND operator (Python native and NumPy ufunc) |
|
|
bitwise OR operator (Python native and NumPy ufunc) |
|
|
inverse of square 2D array |
|
|
pseudo-inverse of 2D array |
|
|
matrix rank of a 2D array |
|
|
solution of a x = b for x |
|
Solve |
solution of x a = b for x |
|
|
singular value decomposition of |
|
|
Cholesky factorization of a 2D array |
|
|
eigenvalues \(\lambda\) and eigenvectors \(v\) of |
|
|
eigenvalues \(\lambda\) and eigenvectors \(v\) of |
|
|
find the |
|
|
QR decomposition |
|
|
LU decomposition with partial pivoting (note: P(MATLAB) == transpose(P(NumPy))) |
|
|
conjugate gradients solver |
|
|
Fourier transform of |
|
|
inverse Fourier transform of |
|
|
sort each column of a 2D array, |
|
|
sort the each row of 2D array, |
|
|
save the array |
|
|
perform a linear regression of the form \(\mathbf{Zx}=\mathbf{y}\) |
|
|
downsample with low-pass filtering |
|
|
a vector of unique values in array |
|
|
remove singleton dimensions of array |
Notes#
Submatrix: Assignment to a submatrix can be done with lists of indices using the ix_ command. E.g., for 2D array a, one might do: ind=[1, 3]; a[np.ix_(ind, ind)] += 100.
HELP: There is no direct equivalent of MATLAB’s which command, but the commands help will usually list the filename where the function is located. Python also has an inspect module (do import inspect) which provides a getfile that often works.
INDEXING: MATLAB uses one based indexing, so the initial element of a sequence has index 1. Python uses zero based indexing, so the initial element of a sequence has index 0. Confusion and flamewars arise because each has advantages and disadvantages. One based indexing is consistent with common human language usage, where the “first” element of a sequence has index 1. Zero based indexing simplifies indexing. See also a text by prof.dr. Edsger W. Dijkstra.
RANGES: In MATLAB, 0:5 can be used as both a range literal and a ‘slice’ index (inside parentheses); however, in Python, constructs like 0:5 can only be used as a slice index (inside square brackets). Thus the somewhat quirky r_ object was created to allow NumPy to have a similarly terse range construction mechanism. Note that r_ is not called like a function or a constructor, but rather indexed using square brackets, which allows the use of Python’s slice syntax in the arguments.
LOGICOPS: & or | in NumPy is bitwise AND/OR, while in MATLAB & and | are logical AND/OR. The two can appear to work the same, but there are important differences. If you would have used MATLAB’s & or | operators, you should use the NumPy ufuncs logical_and/logical_or. The notable differences between MATLAB’s and NumPy’s & and | operators are
Non-logical {0,1} inputs: NumPy’s output is the bitwise AND of the inputs. MATLAB treats any non-zero value as 1 and returns the logical AND. For example
(3 & 4)in NumPy is0, while in MATLAB both3and4are considered logical true and(3 & 4)returns1.Precedence: NumPy’s & operator is higher precedence than logical operators like
<and>; MATLAB’s is the reverse.
If you know you have boolean arguments, you can get away with using NumPy’s bitwise operators, but be careful with parentheses, like this: z = (x > 1) & (x < 2). The absence of NumPy operator forms of logical_and and logical_or is an unfortunate consequence of Python’s design.
重塑和线性索引:MATLAB 始终允许使用标量或线性索引访问多维数组,而 NumPy 不允许。线性索引在 MATLAB 程序中很常见,例如,矩阵上的 find() 返回它们,而 NumPy 的 find 函数行为不同。在转换 MATLAB 代码时,可能需要先将矩阵重塑为线性序列,执行一些索引操作,然后再重塑回来。由于重塑(通常)会生成对同一存储的视图,因此这应该可以相对高效地完成。请注意,NumPy 中 reshape 使用的扫描顺序默认为“C”顺序,而 MATLAB 使用 Fortran 顺序。如果您只是转换为线性序列再转换回来,这无关紧要。但如果您正在转换依赖于扫描顺序的 MATLAB 代码中的重塑,那么 MATLAB 代码: z = reshape(x,3,4); 应该在 NumPy 中变成 z = x.reshape(3,4,order='F').copy()。
‘array’ 还是 ‘matrix’?我应该使用哪个?#
历史上,NumPy 提供了一个特殊的矩阵类型,np.matrix,它是 ndarray 的一个子类,它使二进制运算成为线性代数运算。您可能会在一些现有代码中看到它被用作 np.array 的替代品。那么,应该使用哪个呢?
简短回答#
使用数组(arrays).
它们支持 MATLAB 中支持的多维数组代数
它们是 NumPy 的标准向量/矩阵/张量类型。许多 NumPy 函数返回数组,而不是矩阵。
元素级运算和线性代数运算之间存在明确的区别。
您可以拥有标准的向量或行/列向量(如果您愿意)。
在 Python 3.5 之前,使用数组类型的唯一缺点是您必须使用 dot 而不是 * 来相乘(约简)两个张量(标量积、矩阵向量乘法等)。自 Python 3.5 起,您可以使用矩阵乘法 @ 运算符。
鉴于以上所述,我们计划最终弃用 matrix。
冗长回答#
NumPy 同时包含 array 类和 matrix 类。 array 类旨在成为通用的 n 维数组,用于许多数值计算;而 matrix 则专门用于促进线性代数计算。在实践中,两者之间只有少数几个关键区别。
运算符
*和@,函数dot()和multiply()对于
array,*表示逐元素乘法,而@表示矩阵乘法;它们有相应的函数multiply()和dot()。对于
matrix,*表示矩阵乘法,而要进行逐元素乘法,必须使用multiply()函数。
向量(一维数组)的处理
对于
array,向量形状 1xN、Nx1 和 N 都是不同的概念。诸如A[:,1]之类的操作会返回一个形状为 N 的一维数组,而不是一个形状为 Nx1 的二维数组。一维array的转置不起任何作用。对于
matrix,一维数组总是会被提升为 1xN 或 Nx1 矩阵(行向量或列向量)。A[:,1]返回一个形状为 Nx1 的二维矩阵。
高维数组(ndim > 2)的处理
array对象可以拥有大于 2 的维度数;matrix对象始终只有两个维度。
方便的属性
array有一个 .T 属性,它返回数据的转置。matrix也有 .H、.I 和 .A 属性,它们分别返回共轭转置、逆和矩阵的asarray()。
方便的构造函数
array构造函数接受(嵌套的)Python 序列作为初始化器。例如,array([[1,2,3],[4,5,6]])。matrix构造函数还接受方便的字符串初始化器。例如,matrix("[1 2 3; 4 5 6]")。
两者都有优缺点
array:)逐元素乘法很容易:A*B。:(您必须记住矩阵乘法有自己的运算符,@。:)您可以将一维数组视为行向量或列向量。A @ v将v视为列向量,而v @ A将v视为行向量。这可以省去您输入大量转置操作的麻烦。:)array是 NumPy 的“默认”类型,因此它接受的测试最多,并且是使用 NumPy 的第三方代码最有可能返回的类型。:)能够很好地处理任意维数的数据。:)如果您熟悉张量代数,那么它的语义更接近张量代数。:)所有运算(*、/、+、-等)都是逐元素的。:(来自scipy.sparse的稀疏矩阵与数组的交互效果不太好。
matrix:\\行为更像 MATLAB 矩阵。<:(仅限于二维。要容纳三维数据,您需要array或可能是一个matrix的 Python 列表。<:(最小也只能是二维。您不能拥有向量。它们必须被转换为单列或单行矩阵。<:(由于array是 NumPy 中的默认设置,一些函数即使您将matrix作为参数传递,也可能会返回一个array。这种情况不应该发生在 NumPy 函数上(如果发生,那是一个 bug),但基于 NumPy 的第三方代码可能不会像 NumPy 那样保留类型。:)A*B是矩阵乘法,所以它看起来就像你在线性代数中写的那样(对于 Python >= 3.5,普通数组使用@运算符也有同样的便利性)。<:(逐元素乘法需要调用函数multiply(A,B)。<:(运算符重载的使用有点不合逻辑:*不是逐元素的,但/是。与
scipy.sparse的交互更清晰一些。
因此,强烈建议使用 array。事实上,我们计划最终弃用 matrix。
自定义您的环境#
在 MATLAB 中,您主要用于自定义环境的工具是通过修改搜索路径来添加您喜欢的函数的位置。您可以将此类自定义项放入 MATLAB 启动时会运行的启动脚本中。
NumPy,或者更确切地说 Python,具有类似的功能。
要修改您的 Python 搜索路径以包含您自己的模块位置,请定义
PYTHONPATH环境变量。要使特定的脚本文件在交互式 Python 解释器启动时执行,请定义
PYTHONSTARTUP环境变量,其中包含您的启动脚本的名称。
与 MATLAB 不同,在 MATLAB 中,路径上的任何内容都可以立即调用,而在 Python 中,您需要先执行一个“import”语句才能使特定文件中的函数可访问。
例如,您可以创建一个类似这样的启动脚本(注意:这只是一个示例,并非“最佳实践”的陈述)
# Make all numpy available via shorter 'np' prefix
import numpy as np
#
# Make the SciPy linear algebra functions available as linalg.func()
# e.g. linalg.lu, linalg.eig (for general l*B@u==A@u solution)
from scipy import linalg
#
# Define a Hermitian function
def hermitian(A, **kwargs):
return np.conj(A,**kwargs).T
# Make a shortcut for hermitian:
# hermitian(A) --> H(A)
H = hermitian
使用已弃用的 matrix 和其他 matlib 函数
# Make all matlib functions accessible at the top level via M.func()
import numpy.matlib as M
# Make some matlib functions accessible directly at the top level via, e.g. rand(3,3)
from numpy.matlib import matrix,rand,zeros,ones,empty,eye
链接#
另一个有些过时的 MATLAB/NumPy 交叉引用可以在 https://mathesaurus.sf.net/ 找到。
在 topical software page 中可以找到大量用于 Python 科学工作的工具列表。
有关使用 Python 作为脚本语言的软件列表,请参阅 List of Python software: scripting。
MATLAB® 和 SimuLink® 是 The MathWorks, Inc. 的注册商标。