生成数组的函数
arange
arange
类似于Python中的 range
函数,只不过返回的不是列表,而是数组:
arange(start, stop=None, step=1, dtype=None)
产生一个在区间 [start, stop)
之间,以 step
为间隔的数组,如果只输入一个参数,则默认从 0
开始,并以这个值为结束:
In [1]:
- import numpy as np
- np.arange(4)
Out[1]:
- array([0, 1, 2, 3])
与 range
不同, arange
允许非整数值输入,产生一个非整型的数组:
In [2]:
- np.arange(0, 2 * np.pi, np.pi / 4)
Out[2]:
- array([ 0. , 0.78539816, 1.57079633, 2.35619449, 3.14159265,
- 3.92699082, 4.71238898, 5.49778714])
数组的类型默认由参数 start, stop, step
来确定,也可以指定:
In [3]:
- np.arange(0, 2 * np.pi, np.pi / 4, dtype=np.float32)
Out[3]:
- array([ 0. , 0.78539819, 1.57079637, 2.3561945 , 3.14159274,
- 3.92699099, 4.71238899, 5.49778748], dtype=float32)
由于存在精度问题,使用浮点数可能出现问题:
In [4]:
- np.arange(1.5, 2.1, 0.3)
Out[4]:
- array([ 1.5, 1.8, 2.1])
stop
的值 2.1
出现在了数组中,所以使用浮点数的时候需要注意。
linspace
linspace(start, stop, N)
产生 N
个等距分布在 [start, stop]
间的元素组成的数组,包括 start, stop
。
In [5]:
- np.linspace(0, 1, 5)
Out[5]:
- array([ 0. , 0.25, 0.5 , 0.75, 1. ])
logspace
logspace(start, stop, N)
产生 N 个对数等距分布的数组,默认以10为底:
In [6]:
- np.logspace(0, 1, 5)
Out[6]:
- array([ 1. , 1.77827941, 3.16227766, 5.62341325, 10. ])
产生的值为$\left[10^0, 10^{0.25},10^{0.5},10^{0.75},10^1\right]$。
meshgrid
有时候需要在二维平面中生成一个网格,这时候可以使用 meshgrid
来完成这样的工作:
In [7]:
- x_ticks = np.linspace(-1, 1, 5)
- y_ticks = np.linspace(-1, 1, 5)
- x, y = np.meshgrid(x_ticks, y_ticks)
这里产生的 x, y
如下:
In [8]:
- x
Out[8]:
- array([[-1. , -0.5, 0. , 0.5, 1. ],
- [-1. , -0.5, 0. , 0.5, 1. ],
- [-1. , -0.5, 0. , 0.5, 1. ],
- [-1. , -0.5, 0. , 0.5, 1. ],
- [-1. , -0.5, 0. , 0.5, 1. ]])
In [9]:
- y
Out[9]:
- array([[-1. , -1. , -1. , -1. , -1. ],
- [-0.5, -0.5, -0.5, -0.5, -0.5],
- [ 0. , 0. , 0. , 0. , 0. ],
- [ 0.5, 0.5, 0.5, 0.5, 0.5],
- [ 1. , 1. , 1. , 1. , 1. ]])
x
对应网格的第一维,y
对应网格的第二维。
图例:
In [10]:
- %matplotlib inline
- import matplotlib.pyplot as plt
- from mpl_toolkits.mplot3d import Axes3D
- from matplotlib import cm
- def f(x, y):
- # sinc 函数
- r = np.sqrt(x ** 2 + y ** 2)
- result = np.sin(r) / r
- result[r == 0] = 1.0
- return result
- x_ticks = np.linspace(-10, 10, 51)
- y_ticks = np.linspace(-10, 10, 51)
- x, y = np.meshgrid(x_ticks, y_ticks)
- z = f(x, y)
- fig = plt.figure()
- ax = fig.add_subplot(111, projection='3d')
- ax.plot_surface(x, y, z,
- rstride=1, cstride=1,
- cmap=cm.YlGnBu_r)
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- ax.set_zlabel('z')
- c:\Miniconda\lib\site-packages\IPython\kernel\__main__.py:9: RuntimeWarning: invalid value encountered in divide
Out[10]:
- <matplotlib.text.Text at 0x9ac1630>
事实上,x, y
中有很多冗余的元素,这里提供了一个 sparse
的选项:
In [11]:
- x_ticks = np.linspace(-1, 1, 5)
- y_ticks = np.linspace(-1, 1, 5)
- x, y = np.meshgrid(x_ticks, y_ticks, sparse=True)
In [12]:
- x
Out[12]:
- array([[-1. , -0.5, 0. , 0.5, 1. ]])
In [13]:
- y
Out[13]:
- array([[-1. ],
- [-0.5],
- [ 0. ],
- [ 0.5],
- [ 1. ]])
在这个选项下,x, y
变成了单一的行向量和列向量。
但这并不影响结果:
In [14]:
- x_ticks = np.linspace(-10, 10, 51)
- y_ticks = np.linspace(-10, 10, 51)
- x, y = np.meshgrid(x_ticks, y_ticks, sparse=True)
- z = f(x, y)
- fig = plt.figure()
- ax = fig.add_subplot(111, projection='3d')
- ax.plot_surface(x, y, z,
- rstride=1, cstride=1,
- cmap=cm.YlGnBu_r)
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- ax.set_zlabel('z')
- c:\Miniconda\lib\site-packages\IPython\kernel\__main__.py:9: RuntimeWarning: invalid value encountered in divide
Out[14]:
- <matplotlib.text.Text at 0xba147f0>
meshgrid
可以设置轴排列的先后顺序:
- 默认为
indexing='xy'
即笛卡尔坐标,对于2维数组,返回行向量x
和列向量y
- 或者使用
indexing='ij'
即矩阵坐标,对于2维数组,返回列向量x
和行向量y
。
ogrid , mgrid
Matlab中有 meshgrid
的用法:
meshgrid(-1:.5:1, -1:.5:1)
Numpy的 meshgrid
并不支持这样的用法,但我们可以使用 ogrid / mgrid
来实现类似这样的用法。
ogrid
与 mgrid
的区别在于:
ogrid
相当于meshgrid(indexing='ij', sparse=True)
mgrid
相当于meshgrid(indexing='ij', sparse=False)
In [15]:
- x, y = np.ogrid[-1:1:.5, -1:1:.5]
In [16]:
- x
Out[16]:
- array([[-1. ],
- [-0.5],
- [ 0. ],
- [ 0.5]])
In [17]:
- y
Out[17]:
- array([[-1. , -0.5, 0. , 0.5]])
注意:
- 这里使用的是中括号
- Matlab 使用的是
start:step:end
的表示,Numpy 使用的是start:end:step
的表示 - 这里的结果不包括
end
的值 为了包含end
的值,我们可以使用这样的技巧:
In [18]:
- x, y = np.ogrid[-1:1:5j, -1:1:5j]
In [19]:
- x, y
Out[19]:
- (array([[-1. ],
- [-0.5],
- [ 0. ],
- [ 0.5],
- [ 1. ]]), array([[-1. , -0.5, 0. , 0.5, 1. ]]))
我们在 step
的位置传入一个复数 5j
,表示我们需要一个 5
个值的数组,此时返回值就会包含 end
的值。
重复之前的画图:
In [20]:
- # exchange here
- y, x = np.ogrid[-10:10:51j, -10:10:51j]
- z = f(x, y)
- fig = plt.figure()
- ax = fig.add_subplot(111, projection='3d')
- ax.plot_surface(x, y, z,
- rstride=1, cstride=1,
- cmap=cm.YlGnBu_r)
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- ax.set_zlabel('z')
- c:\Miniconda\lib\site-packages\IPython\kernel\__main__.py:9: RuntimeWarning: invalid value encountered in divide
Out[20]:
- <matplotlib.text.Text at 0x9e34278>
这里,我们交换了 x, y
输出值的顺序。
r , c
我们可以使用 r / c
来产生行向量或者列向量。
使用切片产生:
In [21]:
- np.r_[0:1:.1]
Out[21]:
- array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
复数步长制定数组长度:
In [22]:
- np.r_[0:1:5j]
Out[22]:
- array([ 0. , 0.25, 0.5 , 0.75, 1. ])
连接多个序列,产生数组:
In [23]:
- np.r_[(3,22,11), 4.0, [15, 6]]
Out[23]:
- array([ 3., 22., 11., 4., 15., 6.])
列向量:
In [24]:
- np.c_[1:3:5j]
Out[24]:
- array([[ 1. ],
- [ 1.5],
- [ 2. ],
- [ 2.5],
- [ 3. ]])
ones , zeros
- ones(shape, dtype=float64)
- zeros(shape, dtype=float64)
产生一个制定形状的全 0
或全 1
的数组,还可以制定数组类型:
In [25]:
- np.zeros(3)
Out[25]:
- array([ 0., 0., 0.])
In [26]:
- np.ones([2,3], dtype=np.float32)
Out[26]:
- array([[ 1., 1., 1.],
- [ 1., 1., 1.]], dtype=float32)
产生一个全是 5
的数组:
In [27]:
- np.ones([2,3]) * 5
Out[27]:
- array([[ 5., 5., 5.],
- [ 5., 5., 5.]])
empty
empty(shape, dtype=float64, order='C')
也可以使用 empty
方法产生一个制定大小的数组(数组所指向的内存未被初始化,所以值随机),再用 fill
方法填充:
In [28]:
- a = np.empty(2)
- a
Out[28]:
- array([-0.03412165, 0.05516321])
In [29]:
- a.fill(5)
- a
Out[29]:
- array([ 5., 5.])
另一种替代方法使用索引,不过速度会稍微慢一些:
In [30]:
- a[:] = 5
- a
Out[30]:
- array([ 5., 5.])
empty_like, ones_like, zeros_like
empty_like(a)
ones_like(a)
zeros_like(a)
产生一个跟 a
大小一样,类型一样的对应数组。
In [31]:
- a = np.arange(0, 10, 2.5)
- a
Out[31]:
- array([ 0. , 2.5, 5. , 7.5])
In [32]:
- np.empty_like(a)
Out[32]:
- array([ 0., 0., 0., 0.])
In [33]:
- np.zeros_like(a)
Out[33]:
- array([ 0., 0., 0., 0.])
In [34]:
- np.ones_like(a)
Out[34]:
- array([ 1., 1., 1., 1.])
identity
indentity(n, dtype=float64)
产生一个 n
乘 n
的单位矩阵:
In [35]:
- np.identity(3)
Out[35]:
- array([[ 1., 0., 0.],
- [ 0., 1., 0.],
- [ 0., 0., 1.]])