附录A 高阶Numpy操作
A.2 高阶数组操作
除了神奇索引、切片和布尔值子集外,还有很多方式可以处理数组。虽然大部分数据分析应用程序的繁重工作都是由pandas中的高级函数处理的,但有时候你可能需要编写一些在现有库中找不到的数据算法。
A.2.1 重塑数组
1.一维数组重塑
在很多情况下,你将数组从一个形状转换为另一个形状,并且不复制任何数据。为了实现这个功能,可以向reshape数组实例方法传递一个表示新形状的元组。(见图A-1)例如,假设我们有一个一维数组,我们想要把该数组重新排列进一个矩阵(结果展示在图A-2中)
2.多维数组重塑(见图A-3)
3.reshape的一些操作(见图A-4)
注:如果结果中的值在原始数组中是连续的,则ravel不会生成底层数值的副本。flatten方法的行为类似于ravel,但它总是返回数据的副本(见图A-5)
数据可以按照不同的顺序进行重塑或扁平化。顺序对于新的NumPy用户来说,这是一个有点微妙的主题,因此是下一个子主题。
A.2.2 C顺序和Fortran顺序
NumPy为你提供内存中数据布局的控制和灵活性。默认情况下,NumPy数组是按行方向顺序创建的。在空间上,这意味着如果你有一个二维的数据数组,数组每行中的元素存储在相邻的存储单元中。行方向顺序的替代方法是列方向顺序,这意味着每列数据中的值都存储在相邻的内存位置中。
由于历史原因,行和列方向的顺序也分别称为C顺序和Fortran顺序。在FORTRAN 77语言中,矩阵都是列方向的。
像reshape和ravel函数接收一个order参数,该参数表示数据在数组中使用哪种顺序。在大部分情况下,该参数可以被设置为’C’或’F'(还有一些不太常用的选项’A’和’K'。请参考NumPy官方文档)。(见图A-6)
对二维以上的数组重塑可能会有点令人费解(见图A-3)。C顺序和Fortran顺序的核心区别就是在维度方向上遍历的方式:
C顺序/行方向顺序
首先遍历更高的维度(例如,在轴0上行进之前先在轴1上行进)
Fortran顺序/列方向顺序
最后遍历更高的维度(例如,在轴1上行进之前先在轴0上行进)
A.2.3 连接和分隔数组
1.numpy.concatenate可以获取数组的序列(元组、列表等),并沿着输入轴将它们按顺序连接在一起(见图A-7)
2.使用split将一个数组沿轴向切片成多个数组(见图A-8)
附:全部有关连接和分隔的函数列表,其中一些仅作为通用concatenate的便捷方法(见表A-1)
A.2.3.1 堆叠助手:r 和c
在NumPy命名空间中有两个特殊的对象:r_和c_,它们可以使堆栈数组的操作更为简洁(见图A-9)
这些函数还可以将切片转换为数组(见图A-10)
A.2.4 重复元素:tile和repeat
1.一维数组的重复
repeat和tile函数是用于重复或复制数组的两个有用的工具。repeat函数按照给定次数对数组中的每个元素进行复制,生成一个更大的数组(见图A-11)
注: 对于NumPy而言,复制或重复数组的需求可能不如其他数组编程框架(如MATLAB)那样常见。其中一个原因是广播通常会更好地满足这一需求,这是下一部分的主题。
2.多维数组可以在指定的轴向上对它们的元素进行重复(见图A-12)
注:如果没有传递轴,数组将首先扁平化
3.tile是一种快捷方法,它可以沿着轴向堆叠副本。在视觉上,你可以把它看作类似于“铺设瓷砖”(见图A-13)
注:第二个参数是瓷砖的数量。用标量来说,铺设是逐行进行的,而不是逐列。tile的第二个参数可以是表示“铺瓷砖”布局的元组
A.2.5 神奇索引的等价方法:take和put
如果你回忆第4章,使用整数数组通过神奇索引是获取、设置数组子集的一种方式
还有其他一些ndarray方法可以用于特殊情况下在单个轴上的数据选取(见图A-14)
如果要在别的轴上使用take,可以传递axis关键字(见图A-15)
注:put不接受axis参数,而是将数组索引到扁平版本(一维,C顺序)。因此,当您需要使用其他轴上的索引数组设置元素时,通常最容易使用神奇索引。