|
1 | 1 | <!-- TOC --> |
2 | 2 |
|
3 | 3 | - [和MATLAB的对比](#和matlab的对比) |
4 | | - - [介绍](#介绍) |
5 | | - - [一些关键的差异](#一些关键的差异) |
6 | | - - [‘array’ 还是 ‘matrix’? 我应该选谁?](#array-还是-matrix-我应该选谁) |
7 | | - - [简要的回答](#简要的回答) |
8 | | - - [详细的回答](#详细的回答) |
9 | | - - [使用Matrix的用户的福音](#使用matrix的用户的福音) |
10 | | - - [MATLAB和NumPy粗略的功能对应表](#matlab和numpy粗略的功能对应表) |
11 | | - - [一般功能的对应表](#一般功能的对应表) |
12 | | - - [线性代数功能对应表](#线性代数功能对应表) |
13 | | - - [备注](#备注) |
14 | | - - [自定义环境](#自定义环境) |
15 | | - - [链接](#链接) |
| 4 | + - [介绍](#介绍) |
| 5 | + - [一些关键的差异](#一些关键的差异) |
| 6 | + - [“array” 还是 “matrix”? 我应该选谁?](#array-还是-matrix-我应该选谁) |
| 7 | + - [简要的回答](#简要的回答) |
| 8 | + - [详细的回答](#详细的回答) |
| 9 | + - [使用Matrix的用户的福音](#使用matrix的用户的福音) |
| 10 | + - [MATLAB和NumPy粗略的功能对应表](#matlab和numpy粗略的功能对应表) |
| 11 | + - [一般功能的对应表](#一般功能的对应表) |
| 12 | + - [线性代数功能对应表](#线性代数功能对应表) |
| 13 | + - [备注](#备注) |
| 14 | + - [自定义环境](#自定义环境) |
| 15 | + - [链接](#链接) |
16 | 16 |
|
17 | 17 | <!-- /TOC --> |
18 | 18 | # 和MATLAB的对比 |
19 | 19 |
|
20 | | -> 原文:[NumPy for Matlab users](https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html#numpy-for-matlab-users-notes) |
| 20 | +> 原文:[NumPy for Matlab users](https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html) |
21 | 21 |
|
22 | 22 | ## 介绍 |
23 | 23 |
|
24 | | -MATLAB®和 NumPy/SciPy 有很多共同之处。但是也有很多不同之处。创建NumPy和SciPy是为了用Python最自然的方式进行数值和科学计算,而不是 MATLAB® 的克隆版。本章节旨在收集有关两者的差异,主要是为了帮助熟练的MATLAB®用户成为熟练的NumPy和SciPy用户。 |
| 24 | +MATLAB®和 NumPy/SciPy 有很多共同之处。但是也有很多不同之处。创建NumPy和SciPy是为了用Python以最自然的方式进行数值和科学计算,而不是 MATLAB® 的克隆版。本章节旨在收集有关两者的差异,主要是为了帮助熟练的MATLAB®用户成为熟练的NumPy和SciPy用户。 |
25 | 25 |
|
26 | 26 | ## 一些关键的差异 |
27 | 27 |
|
28 | | -MATLAB | NumPy |
| 28 | +MATLAB® | NumPy |
29 | 29 | ---|--- |
30 | | -在MATLAB®中,基本数据类型是双精度浮点数的多维数组。大多数表达式采用这样的数组并且也返回这样的数据类型,操作这些数组的2-D实例的的方式被设计成或多或少地像线性代数中的矩阵运算一样。 | 在NumPy中,基本类型是多维``数组``。在所有维度(包括2D)上对这些数组的操作都是元素级的操作。对于线性代数,需要使用特定的函数(尽管对于矩阵乘法,可以在python 3.5及以上版本中使用`@`运算符)。 |
| 30 | +在MATLAB®中,基本数据类型是双精度浮点数的多维数组。大多数表达式采用这样的数组并且也返回这样的数据类型,操作这些数组的2-D实例的的方式被设计成或多或少地像线性代数中的矩阵运算一样。 | 在NumPy中,基本类型是多维`数组(array)`。在所有维度(包括2D)上对这些数组的操作都是元素级的操作。对于线性代数,需要使用特定的函数(尽管对于矩阵乘法,可以在python 3.5及以上版本中使用`@`运算符)。 |
31 | 31 | MATLAB®是使用基于1的索引。 使用`a(1)`下标作为元素的初始位置。请参阅[备注](#备注) | Python使用基于0的索引。序列的初始元素使用`a[0]`来查找。 |
32 | | -MATLAB的脚本语言是为做线性代数而创建的。基本矩阵操作的语法很好也很干净,但是用于添加GUI和制作成熟应用程序的API或多或少是事后才想到的。| NumPy基于Python,它从一开始就被设计为一种优秀的通用编程语言。 虽然Matlab的一些数组操作的语法比NumPy更紧凑,但NumPy(由于是Python的附加组件)可以做许多Matlab所不能做的事情,例如将主数组类型子类化为干净地进行数组和矩阵数学运算。 |
33 | | -在 MATLAB® 中,数组具有按值传递的语义,并有一个懒散的写拷贝方案,以防止在真正需要副本之前实际创建副本。使用切片操作复制数组的部分。 | 在NumPy数组,数组只是内存中的引用而已。 切片只是操作数组的视图层面而已。 |
| 32 | +MATLAB的脚本语言是为做线性代数而创建的。基本矩阵操作的语法很好也很简洁,但是用于添加GUI和制作成熟应用程序的API或多或少是事后才想到的。| NumPy基于Python,它从一开始就被设计为一种优秀的通用编程语言。 虽然Matlab的一些数组操作的语法比NumPy更紧凑,但NumPy(由于是Python的附加组件)可以做许多Matlab所不能做的事情,例如正确处理矩阵的堆叠操作。 |
| 33 | +在 MATLAB® 中,数组具有按值传递的语义,采用延迟的“写时复制”(copy-on-write)模式,以防止在实际需要时创建副本。 |
| 34 | +使用切片操作是复制数组的部分。 | 在NumPy数组,在NumPy数组中按引用传递语义。切片操作是数组的视图。 |
34 | 35 |
|
35 | | -## ‘array’ 还是 ‘matrix’? 我应该选谁? |
| 36 | +## “array” 还是 “matrix”? 我应该选谁? |
36 | 37 |
|
37 | | -除了 ``np.ndarray`` 之外,NumPy还提供了一种额外的矩阵类型,你可以在一些现有代码中看到这种类型。想用哪一个呢? |
| 38 | +除了`np.ndarray`之外,NumPy还提供了一种额外的矩阵类型,你可以在一些现有代码中看到这种类型。想用哪一个呢? |
| 39 | + |
| 40 | +由于历史原因,NumPy提供了一种特殊的矩阵类型`np.matrix`,它是ndarray的一个子类,用来做二元运算线性代数运算。您可能会看到一些现有代码中使用它,而不是`np.array`。那么该用哪一个呢? |
38 | 41 |
|
39 | 42 | ### 简要的回答 |
40 | 43 |
|
41 | 44 | **使用 arrays.** |
42 | 45 |
|
43 | | -- 它们是numpy的标准向量/矩阵/张量类型。许多numpy函数返回的是数组,而不是矩阵。 |
44 | | -- 元素级运算和线性代数运算之间有着明确的区别。 |
45 | | -- 如果你愿意,可以使用标准向量或行/列向量。 |
| 46 | +* 它们是numpy的标准向量/矩阵/张量类型。许多numpy函数返回的是数组,而不是矩阵。 |
| 47 | +* 元素级运算和线性代数运算之间有着明确的区别。 |
| 48 | +* 如果你愿意,可以使用标准向量或行/列向量。 |
| 49 | + |
| 50 | +直到Python3.5,使用数组类型的唯一缺点是你必须使用`dot`而不是`*`来将两个张量(标量乘积、矩阵向量乘法等)相乘。从 Python3.5 之后,你就可以使用矩阵乘法运算`@`。 |
46 | 51 |
|
47 | | -直到Python3.5,使用数组类型的唯一缺点是你必须使用 ``dot`` 而不是 ``*`` 来将两个张量(标量乘积、矩阵向量乘法等)相乘(减少)。从 Python3.5 之后,你就可以使用矩阵乘法 ``@`` 运算符。 |
| 52 | +综上所述,我们打算最终弃用`matrix`类型。 |
48 | 53 |
|
49 | 54 | ### 详细的回答 |
50 | 55 |
|
51 | | -NumPy包含 ``array`` 类和 ``Matrix`` 类。 ``array`` 类旨在成为用于多种数值计算的通用n维数组,而 ``matrix`` 类则专门用于促进线性代数计算。实际上,两者之间只有少数几个关键区别。 |
52 | | - |
53 | | -- 操作符 ``*``, ``dot()``, 和 ``multiply()``: |
54 | | - - 对于数组, ``*`` 表示逐元素乘法,而 ``dot()`` 函数用于矩阵乘法。 |
55 | | - - 对于矩阵, ``*`` 表示矩阵乘法, ``multiply()`` 函数用于逐元素乘法。 |
56 | | -- 矢量处理(一维数组) |
57 | | - - 对于数组,向量形状1xN,Nx1和N都是不同的东西。像A [:,1]这样的操作返回形状N的一维数组,而不是形状Nx1的二维数组。一维数组上的转置不起任何作用。 |
58 | | - - 对于矩阵,一维数组总是向上转换为1xN或Nx1矩阵(行或列向量)。A [:,1] 返回形状为Nx1的二维矩阵。 |
59 | | -- 处理更高维数组(ndim> 2) |
60 | | - - 数组对象的维数可以> 2; |
61 | | - - 矩阵对象总是具有两个维度。 |
62 | | -- 便捷的属性 |
63 | | - - ``array``有一个.T属性,它返回数据的转置。 |
64 | | - - ``矩阵``还具有.H,.I和.A属性,分别返回矩阵的共轭转置,反转和 ``asarray()``。 |
65 | | -- 便捷的构造器 |
66 | | - - ``数组``构造函数接受(嵌套的)Pythonseqxues作为初始化器。如 ``array([1,2,3], [4,5,6])``。 |
67 | | - - ``矩阵``构造器另外采用方便的字符串初始化器(传入的参数是字符串)。如 ``matrix("[1 2 3; 4 5 6]")``。 |
| 56 | +NumPy包含`array`类和`Matrix`类。`array`类旨在成为用于多种数值计算的通用n维数组,而`matrix`类则专门用于促进线性代数计算。实际上,两者之间只有少数几个关键区别。 |
| 57 | + |
| 58 | +* 操作符`*`、`@`,函数`dot()`,和`multiply()`: |
| 59 | + * 对于数组,`*`表示元素乘,而`@`表示矩阵乘;它们有相关的函数`multiply()`和`dot()`。(在python 3.5之前,@不存在,必须使用点`dot()`来进行矩阵乘法)。 |
| 60 | + * 对于矩阵,`*`表示矩阵乘法,`multiply()`函数用于逐元素乘法。 |
| 61 | +* 矢量处理(一维数组) |
| 62 | + * 对于数组,向量形状1xN,Nx1和N都是不同的东西。像`A [:,1]`这样的操作返回形状N的一维数组,而不是形状Nx1的二维数组。一维数组上的转置不起任何作用。 |
| 63 | + * 对于矩阵,一维数组总是向上转换为1xN或Nx1矩阵(行或列向量)。`A[:,1]`返回形状为Nx1的二维矩阵。 |
| 64 | +* 处理更高维数组(ndim> 2) |
| 65 | + * 数组对象的维数可以 >2; |
| 66 | + * 矩阵对象总是具有两个维度。 |
| 67 | +* 便捷的属性 |
| 68 | + * 数组有一个.T属性,它返回数据的转置。 |
| 69 | + * 矩阵还具有.H,.I和.A属性,分别返回矩阵的共轭转置,反转和`asarray()`。 |
| 70 | +* 便捷的构造器 |
| 71 | + * 数组构造函数接受(嵌套的)Pythonseqxues作为初始化器。如`array([1,2,3], [4,5,6])`。 |
| 72 | + * 矩阵构造器另外采用方便的字符串初始化器(传入的参数是字符串)。如`matrix("[1 2 3; 4 5 6]")`。 |
68 | 73 |
|
69 | 74 | 使用这两种方法有好处也有坏处: |
70 | 75 |
|
71 | | -- 数组 |
72 | | - - `:)` 你可以将一维数组视为行或列向量。dot(A, v)将v视为列向量,而 ``dot(v,A)``将``v``视为行向量。这可以让你少传入许多的转置。 |
73 | | - - `:(` 必须使用 dot() 函数进行矩阵乘法是很麻烦的 – ``dot(dot(A,B),C)`` vs. ``A*B*C``. 这不是Python> = 3.5的问题,因为``@``运算符允许它写成``A @ B @ C``. |
74 | | - - `:)` 元素乘法很容易,直接:``A*B`` 就好. |
75 | | - - `:)` ``array``是 "默认" 的NumPy类型,因此它获得的支持最多,并且大量的NumPy的第三方包都使用了这个类型。 |
76 | | - - `:)` 它可以更稳定的处理任意数量级的数据。 |
77 | | - - `:)` 如果是熟悉的话,其实它的语义更接近张量代数。 |
78 | | - - `:)` 所有的运算符 (``*``, ``/``, ``+``, ``-``) 都是元素级别的。 |
79 | | -- 矩阵 |
80 | | - - `:\\`行为更像MATLAB®矩阵。 |
81 | | - - `<:(` 它的维度最大为二维,如果你想保存三维数据,你需要数组或者一个矩阵列表。 |
82 | | - - `<:(` 它的维度最少也是二维,你不能有向量还必须将它们转换为单列或单行矩阵。 |
83 | | - - `<:(` 由于 ``array`` 类型是NumPy中的默认类型,因此即使你将``矩阵``作为参数传入,某些函数也可能返回一个 ``array``类型。 |
84 | | -在NumPy的内部函数中应该没有出现可以接受矩阵作为参数的情况(如果有,那它可能是一个bug),但基于NumPy的第三方包可能不像NumPy那样遵守类型规则。 |
85 | | - - `:)` ``A*B`` 是矩阵乘法,因此线性代数更方便(对于Python >= 3.5 的版本,普通数组与 ``@`` 运算符具有同样的方便性)。 |
86 | | - - `<:(` 元素级乘法要求调用乘法函数: ``multiply(A,B)``。 |
87 | | - - `<:(` 操作符重载的使用有点不合逻辑:元素级别中``*``运算符并不会生效, 但是``/``运算符却可以。 |
88 | | - |
89 | | -因此使用``array``是更为可取的。 |
| 76 | +* 数组 |
| 77 | + * `:)` 元素乘法很简单:`A*B` |
| 78 | + * `:(` 你必须记住矩阵乘法有它自己的运算符:`@` |
| 79 | + * `:)` 你可以将一维数组视为行或列向量。`A @ v`将`v`视为列向量,`v @ A`将`v`视为行向量。这可以节省输入大量的转置操作。 |
| 80 | + * `:)` `array`是默认的NumPy类型,因此它得到的测试最多,并且是使用NumPy的第三方代码最有可能返回的类型 |
| 81 | + * `:)` 能处理任意数量维度的数据 |
| 82 | + * `:)` 它的语义更接近张量代数(如果读者对此很熟悉的话) |
| 83 | + * `:)` 所有的运算符 (``*``, ``/``, ``+``, ``-``) 都是元素级别的。 |
| 84 | + * `:(` `scipy.sparse`中的稀疏矩阵不能很好地与数组交互。 |
| 85 | + |
| 86 | +* 矩阵 |
| 87 | + * `:\\` 行为更像MATLAB®矩阵。 |
| 88 | + * `<:(` 它的维度最大为二维,如果你想保存三维数据,你需要数组或者一个矩阵列表。 |
| 89 | + * `<:(` 它的维度最少也是二维,你不能有向量。它们必须将转换为单列或单行矩阵。 |
| 90 | + * `<:(` 由于`array`类型是NumPy中的默认类型,因此即使你将矩阵作为参数传入,某些函数也可能返回一个 `array`类型。这种情况不应该发生在NumPy函数中(如果发生了,那就是一个bug),但是基于NumPy的第三方代码可能不像NumPy那样遵守类型保存。 |
| 91 | + * `:)` `A*B`是矩阵乘法,因此线性代数更方便(对于Python >= 3.5 的版本,普通数组与`@`运算符具有同样的方便性)。 |
| 92 | + * `<:(` 元素级乘法要求调用乘法函数:`multiply(A,B)`。 |
| 93 | + * `<:(` 操作符重载的使用有点不合逻辑:元素级别中`*`运算符并不会生效, 但是`/`运算符却可以。 |
| 94 | + * `:)` 与`scipy.sparse`交互更简介一点 |
| 95 | + |
| 96 | +因此,使用数组要明智得多。事实上,我们打算最终弃用矩阵类型。 |
90 | 97 |
|
91 | 98 | ## 使用Matrix的用户的福音 |
92 | 99 |
|
|
0 commit comments