NumPy 中 ndarray 和 matrix 的区别

本文概述了 NumPy 中 ndarray 和 matrix 的使用差异和转换方法。示例代码假设已导入 numpy

import numpy as np

1. 维数限制

matrix 和 ndarray 所能表示的数据维数不同,matrix 只能表示二维数据,而 ndarray 可以表示 N 维数据。

1.1. matrix

matrix 只能是二维,可以使用如下的方法生成两个 2 * 2 的 matrix:

a = np.mat([[1, 2],[3, 4]])
# a = [[1 2]
#      [3 4]]

b = np.mat('5 6; 7 8');
# b = [[5 6]
#      [7 8]]

如果尝试生成多于二维的矩阵,会产生报错:

c = np.mat([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])  
# ValueError: matrix must be 2-dimensional

1.2. ndarray

ndarray 可以是 N 维,如使用如下的方法生成两个 2 * 2 的 ndarray:

x = np.array([[1, 2], [3, 4]])
# x = [[1 2]
#      [3 4]]
y = np.array([[5, 6], [7, 8]])
# y = [[5 6]
#      [7 8]]

可以生成任意维数的 ndarray:

z = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
# z = [[[1 2]
#       [3 4]]
#
#      [[5 6]
#       [7 8]]]

2. 矩阵乘法

matrix 和 ndarray 在进行矩阵乘法时的操作不同。

2.1. matrix

对于 matrix,使用运算符 * 或 NumPy 的 dot() 方法计算矩阵乘法,使用NumPy 的 multiply() 方法计算逐元素相乘。例如对于上面定义的 matrix ab,有:

a * b
# matrix([[19, 22],
#         [43, 50]])

np.dot(a, b)
# matrix([[19, 22],
#         [43, 50]])

np.multiply(a, b)
# matrix([[ 5, 12],
#         [21, 32]])

2.2. ndarray

对于 ndarray,使用 NumPy 或者 ndarray 的 dot() 方法计算矩阵乘法,使用 运算符 * 或 Numpy 的 multiply() 方法计算逐元素相乘。例如对于上面定义的 ndarray xy,有:

x * y
# array([[ 5, 12],
#        [21, 32]])

x.dot(y)
# array([[19, 22],
#        [43, 50]])

np.dot(x, y)
# array([[19, 22],
#        [43, 50]])

此外,从 Python 3.5 和 Numpy 1.10 以后,可以使用中缀操作符 @ 计算 ndarray 间的矩阵乘法,写起来更加方便:

x @ y
# array([[19, 22],
#        [43, 50]])

3. 转换

3.1. matrix 到 ndarray

可以使用 matrix 的 A 属性或者 NumPy 的 asarray() 方法,将 matrix 转换为 ndarray。如:

d = a.A
type(d) # numpy.ndarray

e = np.asarray(a)
type(e) # numpy.ndarray

注意上面两个转换方法不会复制数据,如果修改了原始 matrix(即 a),则该修改也会反映到转换后的 ndarray(即 de)中,如:

a = np.mat([[1, 2], [3, 4]])

d = a.A
e = np.asarray(a)
print('before change a[0][0]: \nd = \n{}\ne = \n{}'.format(d, e))

a[0][0] = 10

print('\nafter change a[0][0]: \nd = \n{} \ne = \n{}'.format(d, e))

输出为:

before change a[0][0]: 
d = 
[[1 2]
 [3 4]]
e = 
[[1 2]
 [3 4]]

after change a[0][0]: 
d = 
[[10 10]
 [ 3  4]] 
e = 
[[10 10]
 [ 3  4]]

3.2. ndarray 到 matrix

可以使用 Numpy 的 asmatrix() 将 ndarray 转换为 matrix。如:

z = np.asmatrix(x)
type(z) # numpy.matrixlib.defmatrix.matrix

该转换也不会复制数据,如果修改了原始 ndarray(即 x),则该修改也会反映到转换后的 matrix(即 z)中。

4. 如何选择 ndarray 和 matrix

对于 ndarray 和 matrix 的选择,scipy.org 给出的建议是使用 ndarray,因为:

  • They are the standard vector/matrix/tensor type of numpy. Many numpy functions return arrays, not matrices.
  • There is a clear distinction between element-wise operations and linear algebra operations.
  • You can have standard vectors or row/column vectors if you like.