在很多情况下,我们将数组从一个形状转换为另一个形状,并且不复制任何数据。为了实现这个功能,可以向 reshape 数组实例方法传递一个表示新形状的元组。例如,假设我们有一个一维数组,我们想要把该数组重新排列进一个矩阵:
多维数组也可以被重塑:
传递的形状维度可以有一个值是 -1,表示维度通过数据进行推断:
由于数组的 shape 属性是一个元组,它可以被传递给 reshape:
reshape 的反操作可以将更高维度的数组转换为一维数组,这种操作通常被称为 扁平化(flattening)或 分散化(raveling):
flatten() 和 ravel() 实现的功能是一样:
不同之处在于:
在使用过程中flatten()分配了新的内存,返回数据的副本;
ravel() 不会生成底层数值的副本,返回的是一个数组的视图;
原数组和 ravel() / fatten() 返回后的数组的地址并不一样:
在使用过程中应该注意避免在修改视图时影响原本的数组:
对 ravel() 后的结果进行修改时,会影响原本的数组;对 fatten() 后的结果进行修改时,不会原本的数组产生任何影响。
Numpy 提供了内存中数据布局的控制和灵活性。默认情况下,NumPy 数组是按 行方向顺序 创建的。在空间上,这意味着如果你有一个二维的数据数组,数组每行中的元素存储在相邻的存储单元中。行方向顺序的替代方法是列方向顺序,这意味着每列数据中的值都存储在相邻的内存位置中。
由于历史原因,行和列方向的顺序也分别称为 C 顺序 和 Fortran 顺序。在 FORTRAN 77 语言中,矩阵都是列方向上的。
像 reshape 和 ravel 函数接收一个 order 参数,该参数表示数据在数组中使用哪种顺序。在大部分情况下,该参数可以被设置为 "C" 或 "F"(还有一些不太常用的选项 "A" 和 "K"。)
按 C 顺序(行方向)的重塑和按 Fortran 顺序(列方向)的重塑:
C 顺序 和 Fortran 顺序的核心区别就是在维度方向上遍历的方式:
(1) C 顺序 / 行方向顺序
首先遍历更高的维度(例如,在轴 0 上行进之前先在轴 1 上行进)
(2) Fortran 顺序 / 列方向顺序
最后遍历更高的维度(例如,在轴 1 上行进之前先在轴 0 上行进)
1、数组连接函数(其中一些仅作为通用 concatenate 的便捷方法)
函数 | 描述 |
---|---|
concatenate | 最通用的函数,沿一个轴向连接数组的集合 |
vstack, row_stack | 按行堆叠数组(沿着轴0) |
hstack | 按列堆叠数组(沿着轴1) |
column_stack | 类似于 hstack,但会首先把 1 维数组转换为 2 维列向量 |
dstack | 按 “深度” 堆叠数组(沿着轴2) |
split | 沿着指定的轴,在传递的位置上分隔数组 |
hsplit/vsplit | 分别是沿着轴 0 和轴 1 进行分隔的方便函数 |
numpy.concatenate 可以获取数组的序列(元组、列表等),并沿着输入轴将它们按顺序连接在一起:
另一方面,split 可以将一个数组沿轴向切片成多个数组:
传递给 np.split() 的值 [1, 3] 表示将数组拆分时的索引位置。
2、堆叠助手:r_ 和 c_
在 NumPy 命名空间中有两个特殊的对象:r_ 和 c_,它们可以使堆栈数组的操作更为简洁,
np.r_ 中的 r 是 row(行)的缩写,是按行叠加两个矩阵的意思,也可以说是按列连接两个矩阵,就是把两矩阵上下相加,要求列数相等,类似于 pandas 中的 concat()。
np.c_ 中的 c 是 column(列)的缩写,是按列叠加两个矩阵的意思,也可以说是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等,类似于 pandas 中的 merge()。
函数 r_ 和 c_ 可以将切片转换为数组:
repeat 和 tile 函数是用于重复或复制数组的两个有用的工具。
1、repeat
repeat 函数按照给定次数对数组中的每个元素进行复制,生成一个更大的数组:
对于 NumPy 而言,复制或重复数组的需求可能不如其他数组编程框架(如 MATLAB)那样常见。其中一个原因是 广播 通常会更好地满足这一需求。
默认情况下,如果我们传递一个整数,每个元素都会复制相应的次数。如果我们传递了一个整数数组,每个元素都会重复相应的不同次数:
多维数组可以在指定的轴向上对它们的元素进行重复:
注意:如果没有传递轴,数组将首先扁平化,这可能不是我们想要的:
同样,需要按照不同次数重复多维数组的切片时,我们可以传递一个整数数组:
2、tile
title 是一种快捷方法,它可以沿着轴向堆叠副本。在视觉上,我们可以把它看作类似于 “铺设瓷砖”:
第二个参数是瓷砖的数量。用标量来说,铺设是逐行进行的,而不是逐列。tile 的第二个参数可以是表示“铺瓷砖”布局的元组:
使用整数数组通过神奇索引是获取、设置数组子集的一种方式:
1、take
take() 函数用于使用整数数组获取数组子集:
如果要在别的轴上使用 take,我们可以传递 axis 关键字:
2、put
put() 函数用于使用整数数组设置数组子集:
put 不接受 axis 参数,而是将数组索引到扁平版本(一维,C 顺序):