左滑查看目录
![b5672a2fb73648743e618564c97a15f6.png](https://i-blog.csdnimg.cn/blog_migrate/5a0a9745a235df971bfe531d9de4187c.png)
![4619a93ddfb9691b2711c4ca58beb1b9.png](https://i-blog.csdnimg.cn/blog_migrate/b17bf6a79b9f4145c27d1d7af3f8a5cd.png)
![b5672a2fb73648743e618564c97a15f6.png](https://i-blog.csdnimg.cn/blog_migrate/5a0a9745a235df971bfe531d9de4187c.png)
![4619a93ddfb9691b2711c4ca58beb1b9.png](https://i-blog.csdnimg.cn/blog_migrate/b17bf6a79b9f4145c27d1d7af3f8a5cd.png)
形状操纵
我们在创建二维数组的过程中,借助 reshape() 函数,将一维数组转换为矩阵 。>>> a = np.random.random(12)
>>> a
array([ 0.77841574, 0.39654203, 0.38188665, 0.26704305, 0.27519705,
0.78115866, 0.96019214, 0.59328414, 0.52008642, 0.10862692,
0.41894881, 0.73581471])
>>> A = a.reshape(3, 4)
>>> A
array([[ 0.77841574, 0.39654203, 0.38188665, 0.26704305],
[ 0.27519705, 0.78115866, 0.96019214, 0.59328414],
[ 0.52008642, 0.10862692, 0.41894881, 0.73581471]])
reshape()
函数返回一个新的数组,因此可以创建新对象。但是,如果要通过修改形状来修改对象,则必须将包含新尺寸的元组直接分配给它的
形状
attribute。
>>> a.shape = (3, 4)
>>> a
array([[ 0.77841574, 0.39654203, 0.38188665, 0.26704305],
[ 0.27519705, 0.78115866, 0.96019214, 0.59328414],
[ 0.52008642, 0.10862692, 0.41894881, 0.73581471]])
这次是改变形状的起始数组,并且没有返回对象。逆运算也是可能的,即,您可以使用
ravel()
函数将二维数组转换为一维数组。
>>> a = a.ravel()
array([ 0.77841574, 0.39654203, 0.38188665, 0.26704305, 0.27519705,
0.78115866, 0.96019214, 0.59328414, 0.52008642, 0.10862692,
0.41894881, 0.73581471])
甚至在这里直接作用于数组本身的
shape
属性。
>>> a.shape = (12)
>>> a
array([ 0.77841574, 0.39654203, 0.38188665, 0.26704305, 0.27519705,
0.78115866, 0.96019214, 0.59328414, 0.52008642, 0.10862692,
0.41894881, 0.73581471])
另一个重要的操作是转置矩阵,该矩阵将列与行反转。NumPy启用了
transpose()
函数即可提供此功能 。
>>> A.transpose()
array([[ 0.77841574, 0.27519705, 0.52008642],
[ 0.39654203, 0.78115866, 0.10862692],
[ 0.38188665, 0.96019214, 0.41894881],
[ 0.26704305, 0.59328414, 0.73581471]])
阵列操作
通常,我们需要使用已创建的数组再创建一个数组。 下面,你将看到如何通过联接或拆分已定义的数组来创建新数组。连接数组
可以合并多个阵列以形成一个包含所有阵列的新阵列。NumPy使用 堆栈 的概念,为此提供了许多功能。 例如,可以使用 vstack() 函数执行垂直堆栈,该函数将第二个数组合并为第一个数组的新行。 在这种情况下,阵列沿垂直方向生长。 相比之下, hstack() 函数执行水平堆叠。也就是说,第二个数组将添加到第一个数组的列中。>>> A = np.ones((3, 3))
>>> B = np.zeros((3, 3))
>>> np.vstack((A, B))
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> np.hstack((A,B))
array([[ 1., 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0., 0.]])
另外两个函数的多个阵列之间进行堆叠是
column_stack()
一个 第二
row_stack()
。这些功能与之前的两个功能不同。通常,这些功能与一维数组一起使用,这些维数组按列或行堆叠以形成新的二维数组。
>>> a = np.array([0, 1, 2])
>>> b = np.array([3, 4, 5])
>>> c = np.array([6, 7, 8])
>>> np.column_stack((a, b, c))
array([[0, 3, 6],
[1, 4, 7],
[2, 5, 8]])
>>> np.row_stack((a, b, c))
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
分割阵列
在上面,我们了解了如何通过堆叠组装多个阵列。现在,我们将学习如何将数组分为几个部分。在NumPy中,我们可以使用拆分来执行此操作。这里也一样,我们有一组功能的工作水平都与 hsplit() 函数和垂直与 vsplit() 函数。>>> A = np.arange(16).reshape((4, 4))
>>> A
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
因此,如果要水平拆分数组,这意味着将数组的宽度分为两部分,则4x4矩阵A将被拆分为两个2x4矩阵。
>>> [B,C] = np.hsplit(A, 2)
>>> B
array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]])
>>> C
array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])
相反,如果要垂直拆分数组,这意味着将数组的高度分为两部分,则4x4矩阵A将拆分为两个4x2矩阵。
>>> [B,C] = np.vsplit(A, 2)
>>> B
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
>>> C
array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])
一个更复杂的命令是
split()
函数,该函数允许您将数组拆分为非对称部分。将数组作为参数传递时,还必须指定要分割的零件的索引。
如果使用option
axis = 1
,则索引将是列;否则,索引将是列。
相反,如果选项是
axis = 0
,那么它们将是行索引。
例如,如果要将矩阵分为三个部分,其中第一部分将包括第一列,第二部分将包括第二和第三列,第三部分将包括最后一列,则必须在中指定三个索引以下方式。
>>> [A1,A2,A3] = np.split(A,[1,3],axis=1)
>>> A1
array([[ 0],
[ 4],
[ 8],
[12]])
>>> A2
array([[ 1, 2],
[ 5, 6],
[ 9, 10],
[13, 14]])
>>> A3
array([[ 3],
[ 7],
[11],
[15]])
你也可以逐行执行相同的操作。
>>> [A1,A2,A3] = np.split(A,[1,3],axis=0)
>>> A1
array([[0, 1, 2, 3]])
>>> A2
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> A3
array([[12, 13, 14, 15]])
该特征还包括functionaliti 所述的
vsplit()
和
hsplit()
函数。
Numpy的一般概念
下面内容描述了NumPy库的基本概念。副本和视图之间的区别在于它们返回值的时间。本节还介绍了在许多NumPy函数中隐式发生的广播机制。对象的副本或视图
稍微细心一点,你在使用NumPy时就会发现,在处理数组时,你可以返回数组的副本或视图。 Numpy分配均不产生数组的副本,也不包含其中的任何元素。>>> a = np.array([1, 2, 3, 4])
>>> b = a
>>> b
array([1, 2, 3, 4])
>>> a[2] = 0
>>> b
array([1, 2, 0, 4])
如果将一个数组
a
分配给另一个数组
b
,则不是要复制它。数组
b
只是调用数组
a的
另一种方法。实际上,通过更改第三个元素的值,您也可以更改
b
的第三个值。切片数组时,返回的对象是原始数组的视图。
>>> c = a[0:2]
>>> c
array([1, 2])
>>> a[0] = 0
>>> c
array([0, 2])
如上,即使在切片时,实际上也指向同一对象。如果要生成完整且独特的数组,请使用
copy()
函数。
>>> a = np.array([1, 2, 3, 4])
>>> c = a.copy()
>>> c
array([1, 2, 3, 4])
>>> a[0] = 0
>>> c
array([1, 2, 3, 4])
在这种情况下,即使更改 数组
a中的项目
,数组
c
仍保持不变。
向量化
Vectoriz ation和广播是NumPy内部实现的基础。 矢量化是指在开发代码的过程中没有明确的循环。 这些循环实际上是不能省略的,而是在内部实现,然后在代码中被其他构造所取代。 矢量化的应用使得代码更加简洁易读,可以说在外观上会显得更加 "Pythonic"。事实上,得益于向量化,很多操作都有了更加数学化的表达方式。 例如,NumPy允许你表达两个数组的乘法,如下所示: a * b 甚至两个矩阵: A * B 在其他语言中,此类操作将通过许多嵌套循环和 for 构造来表达。例如,第一个操作将以以下方式表示:for (i = 0; i c[i] = a[i]*b[i];}
矩阵的乘积表示如下:
for(i = 0; i for(j = 0; j c [i] [j] = a [i] [j] * b [i] [j];}
你看到了使用NumPy可使代码更具可读性和数学 性。
![5df74b1caa7b35b3f4a3136d167b850b.gif](https://i-blog.csdnimg.cn/blog_migrate/130b83860585a044b49e68ae7246c1ef.gif)