mirror of
https://github.com/apachecn/ailearning.git
synced 2026-04-13 14:29:43 +08:00
683 lines
229 KiB
Markdown
683 lines
229 KiB
Markdown
# 生成数组的函数
|
||
|
||
## arange
|
||
|
||
`arange` 类似于**Python**中的 `range` 函数,只不过返回的不是列表,而是数组:
|
||
|
||
```py
|
||
arange(start, stop=None, step=1, dtype=None)
|
||
```
|
||
|
||
产生一个在区间 `[start, stop)` 之间,以 `step` 为间隔的数组,如果只输入一个参数,则默认从 `0` 开始,并以这个值为结束:
|
||
|
||
In [1]:
|
||
|
||
```py
|
||
import numpy as np
|
||
np.arange(4)
|
||
|
||
```
|
||
|
||
Out[1]:
|
||
|
||
```py
|
||
array([0, 1, 2, 3])
|
||
```
|
||
|
||
与 `range` 不同, `arange` 允许非整数值输入,产生一个非整型的数组:
|
||
|
||
In [2]:
|
||
|
||
```py
|
||
np.arange(0, 2 * np.pi, np.pi / 4)
|
||
|
||
```
|
||
|
||
Out[2]:
|
||
|
||
```py
|
||
array([ 0\. , 0.78539816, 1.57079633, 2.35619449, 3.14159265,
|
||
3.92699082, 4.71238898, 5.49778714])
|
||
```
|
||
|
||
数组的类型默认由参数 `start, stop, step` 来确定,也可以指定:
|
||
|
||
In [3]:
|
||
|
||
```py
|
||
np.arange(0, 2 * np.pi, np.pi / 4, dtype=np.float32)
|
||
|
||
```
|
||
|
||
Out[3]:
|
||
|
||
```py
|
||
array([ 0\. , 0.78539819, 1.57079637, 2.3561945 , 3.14159274,
|
||
3.92699099, 4.71238899, 5.49778748], dtype=float32)
|
||
```
|
||
|
||
由于存在精度问题,使用浮点数可能出现问题:
|
||
|
||
In [4]:
|
||
|
||
```py
|
||
np.arange(1.5, 2.1, 0.3)
|
||
|
||
```
|
||
|
||
Out[4]:
|
||
|
||
```py
|
||
array([ 1.5, 1.8, 2.1])
|
||
```
|
||
|
||
`stop` 的值 `2.1` 出现在了数组中,所以使用浮点数的时候需要注意。
|
||
|
||
## linspace
|
||
|
||
```py
|
||
linspace(start, stop, N)
|
||
```
|
||
|
||
产生 `N` 个等距分布在 `[start, stop]`间的元素组成的数组,包括 `start, stop`。
|
||
|
||
In [5]:
|
||
|
||
```py
|
||
np.linspace(0, 1, 5)
|
||
|
||
```
|
||
|
||
Out[5]:
|
||
|
||
```py
|
||
array([ 0\. , 0.25, 0.5 , 0.75, 1\. ])
|
||
```
|
||
|
||
## logspace
|
||
|
||
```py
|
||
logspace(start, stop, N)
|
||
```
|
||
|
||
产生 N 个对数等距分布的数组,默认以10为底:
|
||
|
||
In [6]:
|
||
|
||
```py
|
||
np.logspace(0, 1, 5)
|
||
|
||
```
|
||
|
||
Out[6]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
x
|
||
|
||
```
|
||
|
||
Out[8]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
y
|
||
|
||
```
|
||
|
||
Out[9]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
%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')
|
||
|
||
```
|
||
|
||
```py
|
||
c:\Miniconda\lib\site-packages\IPython\kernel\__main__.py:9: RuntimeWarning: invalid value encountered in divide
|
||
|
||
```
|
||
|
||
Out[10]:
|
||
|
||
```py
|
||
<matplotlib.text.Text at 0x9ac1630>
|
||
```
|
||
|
||

|
||
|
||
事实上,`x, y` 中有很多冗余的元素,这里提供了一个 `sparse` 的选项:
|
||
|
||
In [11]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
x
|
||
|
||
```
|
||
|
||
Out[12]:
|
||
|
||
```py
|
||
array([[-1\. , -0.5, 0\. , 0.5, 1\. ]])
|
||
```
|
||
|
||
In [13]:
|
||
|
||
```py
|
||
y
|
||
|
||
```
|
||
|
||
Out[13]:
|
||
|
||
```py
|
||
array([[-1\. ],
|
||
[-0.5],
|
||
[ 0\. ],
|
||
[ 0.5],
|
||
[ 1\. ]])
|
||
```
|
||
|
||
在这个选项下,`x, y` 变成了单一的行向量和列向量。
|
||
|
||
但这并不影响结果:
|
||
|
||
In [14]:
|
||
|
||
```py
|
||
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')
|
||
|
||
```
|
||
|
||
```py
|
||
c:\Miniconda\lib\site-packages\IPython\kernel\__main__.py:9: RuntimeWarning: invalid value encountered in divide
|
||
|
||
```
|
||
|
||
Out[14]:
|
||
|
||
```py
|
||
<matplotlib.text.Text at 0xba147f0>
|
||
```
|
||
|
||

|
||
|
||
`meshgrid` 可以设置轴排列的先后顺序:
|
||
|
||
* 默认为 `indexing='xy'` 即笛卡尔坐标,对于2维数组,返回行向量 `x` 和列向量 `y`
|
||
* 或者使用 `indexing='ij'` 即矩阵坐标,对于2维数组,返回列向量 `x` 和行向量 `y`。
|
||
|
||
## ogrid , mgrid
|
||
|
||
**Matlab**中有 `meshgrid` 的用法:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
x, y = np.ogrid[-1:1:.5, -1:1:.5]
|
||
|
||
```
|
||
|
||
In [16]:
|
||
|
||
```py
|
||
x
|
||
|
||
```
|
||
|
||
Out[16]:
|
||
|
||
```py
|
||
array([[-1\. ],
|
||
[-0.5],
|
||
[ 0\. ],
|
||
[ 0.5]])
|
||
```
|
||
|
||
In [17]:
|
||
|
||
```py
|
||
y
|
||
|
||
```
|
||
|
||
Out[17]:
|
||
|
||
```py
|
||
array([[-1\. , -0.5, 0\. , 0.5]])
|
||
```
|
||
|
||
注意:
|
||
|
||
* 这里使用的是中括号
|
||
* **Matlab** 使用的是 `start:step:end` 的表示,**Numpy** 使用的是 `start:end:step` 的表示
|
||
* 这里的结果不包括 `end` 的值
|
||
|
||
为了包含 `end` 的值,我们可以使用这样的技巧:
|
||
|
||
In [18]:
|
||
|
||
```py
|
||
x, y = np.ogrid[-1:1:5j, -1:1:5j]
|
||
|
||
```
|
||
|
||
In [19]:
|
||
|
||
```py
|
||
x, y
|
||
|
||
```
|
||
|
||
Out[19]:
|
||
|
||
```py
|
||
(array([[-1\. ],
|
||
[-0.5],
|
||
[ 0\. ],
|
||
[ 0.5],
|
||
[ 1\. ]]), array([[-1\. , -0.5, 0\. , 0.5, 1\. ]]))
|
||
```
|
||
|
||
我们在 `step` 的位置传入一个复数 `5j` ,表示我们需要一个 `5` 个值的数组,此时返回值就会包含 `end` 的值。
|
||
|
||
重复之前的画图:
|
||
|
||
In [20]:
|
||
|
||
```py
|
||
# 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')
|
||
|
||
```
|
||
|
||
```py
|
||
c:\Miniconda\lib\site-packages\IPython\kernel\__main__.py:9: RuntimeWarning: invalid value encountered in divide
|
||
|
||
```
|
||
|
||
Out[20]:
|
||
|
||
```py
|
||
<matplotlib.text.Text at 0x9e34278>
|
||
```
|
||
|
||

|
||
|
||
这里,我们交换了 `x, y` 输出值的顺序。
|
||
|
||
## r`_` , c`_`
|
||
|
||
我们可以使用 `r_ / c_` 来产生行向量或者列向量。
|
||
|
||
使用切片产生:
|
||
|
||
In [21]:
|
||
|
||
```py
|
||
np.r_[0:1:.1]
|
||
|
||
```
|
||
|
||
Out[21]:
|
||
|
||
```py
|
||
array([ 0\. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
|
||
```
|
||
|
||
复数步长制定数组长度:
|
||
|
||
In [22]:
|
||
|
||
```py
|
||
np.r_[0:1:5j]
|
||
|
||
```
|
||
|
||
Out[22]:
|
||
|
||
```py
|
||
array([ 0\. , 0.25, 0.5 , 0.75, 1\. ])
|
||
```
|
||
|
||
连接多个序列,产生数组:
|
||
|
||
In [23]:
|
||
|
||
```py
|
||
np.r_[(3,22,11), 4.0, [15, 6]]
|
||
|
||
```
|
||
|
||
Out[23]:
|
||
|
||
```py
|
||
array([ 3., 22., 11., 4., 15., 6.])
|
||
```
|
||
|
||
列向量:
|
||
|
||
In [24]:
|
||
|
||
```py
|
||
np.c_[1:3:5j]
|
||
|
||
```
|
||
|
||
Out[24]:
|
||
|
||
```py
|
||
array([[ 1\. ],
|
||
[ 1.5],
|
||
[ 2\. ],
|
||
[ 2.5],
|
||
[ 3\. ]])
|
||
```
|
||
|
||
## ones , zeros
|
||
|
||
```py
|
||
ones(shape, dtype=float64)
|
||
zeros(shape, dtype=float64)
|
||
|
||
```
|
||
|
||
产生一个制定形状的全 `0` 或全 `1` 的数组,还可以制定数组类型:
|
||
|
||
In [25]:
|
||
|
||
```py
|
||
np.zeros(3)
|
||
|
||
```
|
||
|
||
Out[25]:
|
||
|
||
```py
|
||
array([ 0., 0., 0.])
|
||
```
|
||
|
||
In [26]:
|
||
|
||
```py
|
||
np.ones([2,3], dtype=np.float32)
|
||
|
||
```
|
||
|
||
Out[26]:
|
||
|
||
```py
|
||
array([[ 1., 1., 1.],
|
||
[ 1., 1., 1.]], dtype=float32)
|
||
```
|
||
|
||
产生一个全是 `5` 的数组:
|
||
|
||
In [27]:
|
||
|
||
```py
|
||
np.ones([2,3]) * 5
|
||
|
||
```
|
||
|
||
Out[27]:
|
||
|
||
```py
|
||
array([[ 5., 5., 5.],
|
||
[ 5., 5., 5.]])
|
||
```
|
||
|
||
## empty
|
||
|
||
```py
|
||
empty(shape, dtype=float64, order='C')
|
||
```
|
||
|
||
也可以使用 `empty` 方法产生一个制定大小的数组(数组所指向的内存未被初始化,所以值随机),再用 `fill` 方法填充:
|
||
|
||
In [28]:
|
||
|
||
```py
|
||
a = np.empty(2)
|
||
a
|
||
|
||
```
|
||
|
||
Out[28]:
|
||
|
||
```py
|
||
array([-0.03412165, 0.05516321])
|
||
```
|
||
|
||
In [29]:
|
||
|
||
```py
|
||
a.fill(5)
|
||
a
|
||
|
||
```
|
||
|
||
Out[29]:
|
||
|
||
```py
|
||
array([ 5., 5.])
|
||
```
|
||
|
||
另一种替代方法使用索引,不过速度会稍微慢一些:
|
||
|
||
In [30]:
|
||
|
||
```py
|
||
a[:] = 5
|
||
a
|
||
|
||
```
|
||
|
||
Out[30]:
|
||
|
||
```py
|
||
array([ 5., 5.])
|
||
```
|
||
|
||
## empty`_`like, ones`_`like, zeros`_`like
|
||
|
||
```py
|
||
empty_like(a)
|
||
ones_like(a)
|
||
zeros_like(a)
|
||
```
|
||
|
||
产生一个跟 `a` 大小一样,类型一样的对应数组。
|
||
|
||
In [31]:
|
||
|
||
```py
|
||
a = np.arange(0, 10, 2.5)
|
||
a
|
||
|
||
```
|
||
|
||
Out[31]:
|
||
|
||
```py
|
||
array([ 0\. , 2.5, 5\. , 7.5])
|
||
```
|
||
|
||
In [32]:
|
||
|
||
```py
|
||
np.empty_like(a)
|
||
|
||
```
|
||
|
||
Out[32]:
|
||
|
||
```py
|
||
array([ 0., 0., 0., 0.])
|
||
```
|
||
|
||
In [33]:
|
||
|
||
```py
|
||
np.zeros_like(a)
|
||
|
||
```
|
||
|
||
Out[33]:
|
||
|
||
```py
|
||
array([ 0., 0., 0., 0.])
|
||
```
|
||
|
||
In [34]:
|
||
|
||
```py
|
||
np.ones_like(a)
|
||
|
||
```
|
||
|
||
Out[34]:
|
||
|
||
```py
|
||
array([ 1., 1., 1., 1.])
|
||
```
|
||
|
||
## identity
|
||
|
||
```py
|
||
indentity(n, dtype=float64)
|
||
```
|
||
|
||
产生一个 `n` 乘 `n` 的单位矩阵:
|
||
|
||
In [35]:
|
||
|
||
```py
|
||
np.identity(3)
|
||
|
||
```
|
||
|
||
Out[35]:
|
||
|
||
```py
|
||
array([[ 1., 0., 0.],
|
||
[ 0., 1., 0.],
|
||
[ 0., 0., 1.]])
|
||
``` |