文章目录
- 单值数组
- 特殊矩阵
- 范德蒙德矩阵
- 数值范围
- 坐标网格
- 绘图代码
所有创建数组的函数中,都有一个可选参数dtype
,表示创建的数组的数据类型。
指定维度 | empty, eye, identity, ones, zeros, full |
模仿维度 | empty_like, ones_like, zeros_like, full_like |
特殊矩阵 | diag, diagflat, tri, tril, triu, vander |
数值范围 | arange, linspace, logspace, geomspace |
坐标网格 | meshgrid, mgrid, ogrid, indices |
单值数组
empty
生成指定维度的空数组。
ones
, zeros
和full
生成所有元素都相同的数组,顾名思义ones和zeros分别是全1和全0的数组,而full则可以指定其fill_value
,例如
np.ones(3) #生成全1的3x1数组
np.zeros([2,3]) #生成全0的2x3数组
x = np.full([2,4], 5) #生成元素均为5的2x4数组
以_like
为后缀的函数,表示生成一个和输入数组维度相同的数组,以ones为例,np.ones_like(x)
等价于np.ones(x.shape)
。
>>> y = np.full_like(x, 6)
特殊矩阵
eye
和identity
都是生成对角为1,其他元素为0的矩阵,区别在于,identity
只能生成单位矩阵,即方阵;而eye
则可以生成行列数不同的矩阵。diagflat
和diag
用于生成对角矩阵,下面用图像的方式,来表现这四种对角矩阵
这些矩阵的生成方式就是每个子图标题中所显示的,完整的绘图代码附在文末。
diag
在diagflat
基础上,还可以提取对角元素,例如
>>> np.diag(np.ones([3,3])) #提取对角元素
array([1., 1., 1.])
tri(M,N,k)用于生成M行N列的三角阵,其元素为0或者1,k用于调节0和1的分界线相对于对角线的位置,下图中,红色表示1,蓝色表示0.
tril, triu
可用于提取出矩阵的左下和右上的三角阵,其输入参数除了待提取矩阵之外,另一个参数与tri
中的k
相同,把x设为
x = np.arange(20).reshape(4, 5)
则tril
和triu
作用在x上的效果分别如下,二者分别把右上角和左下角的值变成了0。
范德蒙德矩阵
范德蒙德矩阵可表示为
[ 1 α 1 α 1 2 ⋯ α 1 n 1 α 2 α 2 2 ⋯ α 2 n ⋮ ⋮ ⋮ 2 ⋯ ⋮ n 1 α m α m 2 ⋯ α m n ] \begin{bmatrix} 1&\alpha_1&\alpha_1^2&\cdots&\alpha_1^n\\ 1&\alpha_2&\alpha_2^2&\cdots&\alpha_2^n\\ \vdots&\vdots&\vdots^2&\cdots&\vdots^n\\ 1&\alpha_m&\alpha_m^2&\cdots&\alpha_m^n \end{bmatrix} 11⋮1α1α2⋮αmα12α22⋮2αm2⋯⋯⋯⋯α1nα2n⋮nαmn
np.vander
可通过给定的
α
i
\alpha_i
αi生成范德蒙德矩阵,例如
x = np.array([1, 2, 3, 5])
y = np.vander(x, increasing=True)
其结果为
y = [ 1 1 1 1 1 2 4 8 1 3 6 9 1 5 25 125 ] y=\begin{bmatrix} 1&1&1&1\\1&2&4&8\\1&3&6&9\\1&5&25&125 \end{bmatrix} y= 1111123514625189125
数值范围
arange是Numpy中使用频率超高的一个数组生成器,其输入参数可以为一个、两个或者三个,调用结果如下图,其中横轴表示生成数组的下标,纵轴表示值
与arange
作用相似的函数是linspace
,其输入参数为np.linspace(a,b,num)
,表示在
a
,
b
a,b
a,b之间等间隔生成num
个数;如果指明endpoint=False
,则不包含
b
b
b点。
np.linspace(1,2,5) # [1. , 1.25, 1.5 , 1.75, 2. ]
linspace
和arange
非常相似,区别如下
linspace(a,b,N)
在 [ a , b ] [a,b] [a,b]中间生成N个值arange(a,b,delta)
在 [ a , b ) [a,b) [a,b)之间,以 d e l t a delta delta为间隔生成值
logspace
与linspace
逻辑相似,都是在某个区间内等间隔生成数组,但logspace
是对数意义上的等间隔,其等价于10**np.linspace
。
print(np.logspace(1,2,5))
# [ 10. 17.7827941 31.6227766 56.23413252 100. ]
print(10**np.linspace(1,2,5))
# [ 10. 17.7827941 31.6227766 56.23413252 100. ]
logspace
中的base
参数,可以指定对数的底,例如
>>> print(np.logspace(1,2,5,base=2))
[2. 2.37841423 2.82842712 3.36358566 4.]
geomspace
同样是等间隔生成对数,但和logspace
的区别是,同样在a,b
区间内生成对数,logspace
生成范围是
[
1
0
a
,
1
0
b
]
[10^a,10^b]
[10a,10b],geomspace
的范围则是
[
a
,
b
]
[a,b]
[a,b]。
>>> print(np.geomspace(1,2,5))
[1. 1.18920712 1.41421356 1.68179283 2.]
这种区别可能过于微妙,画个图可能理解起来更加容易
对比如下
最后,总结一下这三个space
函数的区别
linspace(a,b,N)
在 [ a , b ] [a,b] [a,b]中间生成N个值logspace(a,b,N,base=c)
在 [ c a , c b ] [c^a, c^b] [ca,cb]之间等指数间隔生成N个值geomspace(a,b,N,base=c)
在 [ a , b ] [a,b] [a,b]之间,等指数间隔生成N个值
坐标网格
在三维图的绘制过程中,一般需要 x , y , z x,y,z x,y,z之间的对应关系,但对于图像而言,其 x , y x,y x,y轴坐标是体现在像素栅格中的,从而图像矩阵中的像素强度,其实表示的是 z z z轴的坐标,这种情况下如果想绘制三维散点图,就需要生成图像像素对应的坐标网格。
在Numpy
中,最常用的坐标网格生成函数,就是meshgrid
,其用法可参考下面的示例
x = [0,1,2,3,4]
y = [0,1,2,3]
xv, yv = np.meshgrid(x, y)
其中
x v = [ 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 ] y v = [ 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 ] x_v=\begin{bmatrix} 0&1&2&3&4\\0&1&2&3&4\\0&1&2&3&4\\0&1&2&3&4\\ \end{bmatrix}\quad y_v=\begin{bmatrix} 0&0&0&0&0\\1&1&1&1&1\\2&2&2&2&2\\3&3&3&3&3\\ \end{bmatrix} xv= 00001111222233334444 yv= 01230123012301230123
直观地说,就是对输入的 x , y x,y x,y变量,分别向 y y y轴和 x x x轴方向进行了扩张。
mgrid
比meshgrid
更加简单,可以直接通过魔法函数生成坐标网格。
>>> xv, yv = np.mgrid[0:2, 2:5]
>>> print(xv)
[[0 0 0]
[1 1 1]]
>>> print(yv)
[[2 3 4]
[2 3 4]]
当然,这个维度和步长可以任意选择,
>>> np.mgrid[1:5]
array([1, 2, 3, 4])
>>> np.mgrid[1:10:5]
array([1, 6])
>>> np.mgrid[1.1:10]
array([1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1, 9.1])
如果翻阅源码,会发现mgrid
是MGridClass()
的一个实例,MGridClass
则是nd_grid
的一个子类,在nd_grid
中,实现了__getitem__
这个魔法函数,从而达成了[]
的索引方法。
ogrid
的用法与mgrid
相同,二者都是nd_grid
的子类,但生成的数组不同,直接看案例
>>>x,y = ogrid[0:5,0:5]
其中, x = [ 0 , 1 , 2 , 3 , 4 ] T x=[0,1,2,3,4]^T x=[0,1,2,3,4]T, y = [ 0 , 1 , 2 , 3 , 4 ] y=[0,1,2,3,4] y=[0,1,2,3,4]。
如果想干脆一点,只是生成从0开始的等间隔的坐标网格,那么这里最推荐的是indices
,这个函数只需输入维度,就可以完成网格的创建。
接下来打开一张图片演示一下
import numpy as np
import matplotlib.pyplot as plt
img = plt.imread('test.jpg')
ax = plt.subplot(projection='3d')
gray = img[:,:,1]
yMat, xMat = np.indices(gray.shape)
ax.plot_surface(xMat, yMat, gray)
ax.axis('off')
plt.show()
效果为
绘图代码
对角矩阵
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(9,3))
ax = fig.add_subplot(141)
ax.imshow(np.identity(5))
plt.title("np.identity(5)")
ax = fig.add_subplot(142)
ax.imshow(np.eye(5,3))
plt.title("np.eye(5,3)")
ax = fig.add_subplot(143)
ax.imshow(np.diagflat([1,2,3]))
plt.title("np.diagflat([1,2,3])")
ax = fig.add_subplot(144)
ax.imshow(np.diag([1,2,3]))
plt.title("np.diag([1,2,3])")
plt.colorbar()
plt.tight_layout()
plt.show()
tri矩阵
fig = plt.figure(figsize=(9,4))
cmap = plt.get_cmap('jet')
for i in range(6):
ax = fig.add_subplot(2,3,i+1)
ax.invert_yaxis()
ax.pcolor(np.tri(4,6,i), edgecolors='k', cmap=cmap)
plt.title(f"np.tri(4,6,{i})")
plt.tight_layout()
plt.show()
tril和triu
x = np.arange(20).reshape(4, 5)
fig = plt.figure(figsize=(9,4))
ax = fig.add_subplot(121)
ax.invert_yaxis()
ax.imshow(np.tril(x,-1), cmap=cmap)
plt.title(f"np.tril(x,-1)")
ax = fig.add_subplot(122)
ax.invert_yaxis()
ax.imshow(np.triu(x,-1), cmap=cmap)
plt.title(f"np.triu(x,-1)")
plt.tight_layout()
plt.show()
arange
fig = plt.figure(figsize=(9,3))
ax = fig.add_subplot(131)
plt.stem(np.arange(10))
plt.title("np.arange(10)")
ax = fig.add_subplot(132)
plt.stem(np.arange(3,10))
plt.title("np.arange(3,10)")
ax = fig.add_subplot(133)
plt.stem(np.arange(3,10,2))
plt.title("np.arange(3,10,2)")
plt.tight_layout()
plt.show()
logspace和geospace
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(1,2,20)
y = {"logspace" : np.logspace(1,2,20),
"geomspace" : np.geomspace(1,2,20)}
fig = plt.figure()
for i,key in zip([1,2],y.keys()):
ax = fig.add_subplot(1,2,i)
ax.plot(x,y[key],marker="*")
ax.set_title(key)
plt.show()