NumPy 小知识

mgrid

np.mgrid 初始化方法,在某些时候是非常有用的。

>>> np.mgrid[0:3,0:3]
array([[[0, 0, 0],
        [1, 1, 1],
        [2, 2, 2]],

       [[0, 1, 2],
        [0, 1, 2],
        [0, 1, 2]]])

类似的方法, 从已有序列构造:np.meshgrid(x1, x2), 另外可以直接解包, a, b = np.meshgrid(x1, x2)

>>> np.meshgrid([0,1,2], [0,2,3])
[array([[0, 1, 2],
        [0, 1, 2],
        [0, 1, 2]]), array([[0, 0, 0],
        [2, 2, 2],
        [3, 3, 3]])]


## 另一种 index 方法

类似于断点型切片

```python
>>> Z = np.arange(9).reshape(3,3)
>>> Z
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> Z[[0,1],[0,2]]
array([0, 5])

此时的 index 是按维度给出的,且得到的结果是 1 维的

ndarray 和 matrix 的区别

参考:What are the differences between numpy arrays and matrices? Which one should I use?

matrix 是严格 2 维的,而 ndarray 可以是 n 维的,matrix 是 ndarray 的一个子集,拥有全部 ndarray 的方法。matrix 主要的好处是可以方便的进行矩阵乘法,a*b 是矩阵乘法

import numpy as np

a=np.mat('4 3; 2 1')
b=np.mat('1 2; 3 4')
print(a)
# [[4 3]
#  [2 1]]
print(b)
# [[1 2]
#  [3 4]]
print(a*b)
# [[13 20]
#  [ 5  8]]

不过在 Python 3.5 以后的版本,NumPy 支持 ndaaray 的 @ 操作符,同样也是矩阵乘法,

import numpy as np

a=np.array([[4, 3], [2, 1]])
b=np.array([[1, 2], [3, 4]])
print(a@b)
# [[13 20]
#  [ 5  8]]

matrix 和 ndarray 都有 .T 方法,但是 matrix 还有 .I 逆矩阵和 .H 共轭矩阵方法,由于 * 操作符功能的不同, ** 操作符的功能也不一样

可以通过 np.asmatrixnp.asarray 相互转换两种类型

一个奇怪的特性

ndarray 会在切片选择时自动把 向量一维化,比如(n, m) shape 的 array 切一列,自动变为 (n,) shape,这两种 shape 在进行矩阵运算时是很不一样的,毕竟 (n,) shape 的 array 转置 T 还是本身。而 matrix 对象默认 2 维

s = np.random.random((3, 4))
sli = s[:, 2]
smat = np.asmatrix(np.random.random((3, 4)))
smatsli = smat[:, 2]
>>> s
[[0.74826837 0.54473159 0.09496908 0.01146775]
 [0.29463775 0.5483382  0.81112557 0.74412076]
 [0.52261503 0.10080661 0.50683063 0.0232837 ]]
>>> sli
array([0.09496908, 0.81112557, 0.50683063])
>>> sli.shape
(3,) # (3, 1) -> (3,)
>>> sli.T
array([0.09496908, 0.81112557, 0.50683063])
>>> smatsli
matrix([[0.71810086],
        [0.8686908 ],
        [0.09933655]])
>>> smatsli.shape
(3, 1)

在很多矩阵操作中要用到列向量或者横向量,如果为了保持编程的一致性而不适用 matrix,那么一个这种的解决办法就是在可能发生 NumPy 1D 化的地方增加一个 reshape(n, 1) 的操作,必要的时候放一个 assert 语句保证不出错

Matrix library (numpy.matlib)

这个库拥有所有 NumPy 命名空间的函数,只是针对 matrix 替换了以下函数。

numpy namespace 中返回 matrix 的函数

mat(data[, dtype])  Interpret the input as a matrix.
matrix  Returns a matrix from an array-like object, or from a string of data.
asmatrix(data[, dtype]) Interpret the input as a matrix.
bmat(obj[, ldict, gdict])   Build a matrix object from a string, nested sequence, or array.

matlib 库中替换了的函数

empty(shape[, dtype, order])    Return a new matrix of given shape and type, without initializing entries.
zeros(shape[, dtype, order])    Return a matrix of given shape and type, filled with zeros.
ones(shape[, dtype, order]) Matrix of ones.
eye(n[, M, k, dtype])   Return a matrix with ones on the diagonal and zeros elsewhere.
identity(n[, dtype])    Returns the square identity matrix of given size.
repmat(a, m, n) Repeat a 0-D to 2-D array or matrix MxN times.
rand(*args) Return a matrix of random values with given shape.
randn(*args)    Return a random matrix with data from the “standard normal” distribution.

numpy.argwhere

>>> x = np.arange(6).reshape(2,3)
>>> x
array([[0, 1, 2],
       [3, 4, 5]])

>>> np.argwhere(x>1)
array([[0, 2],
       [1, 0],
       [1, 1],
       [1, 2]])

此处给出的结果是一个个的 “坐标”

numpy.where

numpy.where(condition[, x, y])

如果输入了 x, y 且是 1 维的,相当于

[xv if c else yv for (c,xv,yv) in zip(condition,x,y)]

>>> np.where([[True, False], [True, True]],
...          [[1, 2], [3, 4]],
...          [[9, 8], [7, 6]])
array([[1, 8],
       [3, 4]])
>>> np.where([[0, 1], [1, 0]])
(array([0, 1]), array([1, 0]))

认为条件是 True

>>> x = np.arange(9.).reshape(3, 3)
>>> np.where( x > 5 )
(array([2, 2, 2]), array([0, 1, 2]))     # 可以理解为以 grid 为 x 进行操作,但是 False 的值会直接舍弃,而不是取 y
>>> x[np.where( x > 3.0 )]               # 结果是 1D.
array([ 4.,  5.,  6.,  7.,  8.])
>>> np.where(x < 5, x, -1)               # 相当于二元操作符.
array([[ 0.,  1.,  2.],
       [ 3.,  4., -1.],
       [-1., -1., -1.]])

注意:对 ndarray 采用这种 index 方式得到的结果是 1 维的,还可以进行类似与二元操作的运算,另外注意 where 给出的位置是按轴排列的,而 argwhere 是按坐标给出的。

此外还有类似的 numpy.nonzero()