您的位置:首页 > 编程语言 > Python开发

Python数据分析 | (9)NumPy数组高级操作---变型、重塑、扁平、合并拆分以及重复

2019-01-12 12:45 796 查看

本篇博客所有示例使用Jupyter NoteBook演示。

Python数据分析系列笔记基于:利用Python进行数据分析(第2版)  

目录

1.数组转置和轴对换

2.数组重塑

3.数组扁平化

4.数组的合并和拆分

5.元素的重复操作:tile/repeat

1.数组转置和轴对换

转置是重塑的一种特殊形式,返回的是源数据的视图(不会进行任何复制操作).

  • 二维数组

2维数组转置不仅有transpose方法,还有一个特殊的T属性:

[code]import numpy as np

arr = np.arange(15).reshape((3,5))
print(arr.T)     #返回源数组arr的视图  arr没有任何改变  arr.T/arr.transpose()返回arr的视图
print(arr.transpose()) #如果赋值给一个新数组 对新数组进行修改 arr也会改变
print(arr)

进行矩阵运算时,经常要用到转置操作,比如利用np.dot计算矩阵内积时:

[code]arr = np.random.randn(6,3)
print(arr)
print(np.dot(arr.T,arr))  #(3,6) (6,3)->(3,3)

  • 高维数组

对于高维数组,transpose函数需要得到一个由轴编号组成的元组才能对轴进行转置:

[code]arr = np.arange(16).reshape((2,2,4))
print(arr)
print("---------------")
print(arr.transpose(1,0,2))

这里0轴和1轴互换,2轴不变。

2维数组简单的转置可以使用.T,他其实就是进行轴对换而已。ndarray还有一个swapaxes函数,需要接受一对轴编号:

[code]print(arr)
print("--------------")
print(arr.swapaxes(1,2))

swapaxes函数和transpose,.T一样,也是返回源数据的视图(不会进行任何复制操作)

2.数组重塑

多数情况下,可以无需复制任何数据,就可以将数组从一个形状转换为另一个形状。只需要向数组的函数reshape传入一个表示新形状的元组即可。

将一个一维数组重新排列成一个矩阵(2维数组):

[code]arr = np.arange(8)
print(arr)
print(arr.reshape((4,2)))  #返回arr的视图

reshape函数还有一个order参数,两个取值:'C'表示C order,行优先顺序;'F'表示F order,列优先顺序。默认是C order。如下图所示:

 多维数组也能被重塑:

[code]print(arr.reshape((4,2)).reshape((2,4)))

作为参数的形状的其中一维可以是-1,表示该维度的大小由数据本身推断而来:

[code]arr = np.arange(15)
print(arr.reshape((5,-1)))  #-1让numpy自动计算  15/5=3

3.数组扁平化

与reshape将一维数组转换为多维数组的运算相反的运算称为扁平化flattening或散开raveling:

[code]arr = np.arange(15).reshape((5,3))
print(arr)
print(arr.ravel())  #返回源数组的视图
print(arr.flatten())  #效果和ravel相同 返回源数组的副本

C和Fortran顺序:

数组的重塑和散开可以按照两种不同的顺序。NumPy允许我们更为灵活地控制数据在内存中的布局。默认情况下NumPy数组是按行优先顺序创建的,重塑和散开也是默认为行优先顺序,即C顺序。在空间方面,意味着对于一个2维数组,每行中的数据项被存放在相邻的内存位置上。另一种顺序是列优先顺序,即F顺序,意味着每列中的数据项是被存放在相邻内存位置上的。

像reshape和reval/flatten这样的函数,都可以接受一个表示数组存放顺序的order参数。一般可以是'C'或'F'(还有'A','K'等不常用选项,具体参考NumPy文档):

[code]arr = np.arange(12).reshape((3,4))
print(arr)
print(arr.ravel())  #默认为C顺序 行优先   返回数组视图
print(arr.ravel('F')) #可以设置为F顺序 列优先 返回数组视图

2维数组或高维数组的重塑过程比较令人费解。C和Fortran顺序的关键区别就是维度的行进顺序:

C/行优先顺序:先经过更高的维度(如,轴1会先于轴0被处理)

F/列优先顺序:后经过更高的维度(如,轴0会先于轴1被处理)

默认情况下,都是C顺序。

4.数组的合并和拆分

np.concatenate可以按指定轴将一个由数组组成的序列(如元组、列表等)连接在一起:

[code]arr1 = np.array([[1,2,3],[4,5,6]])
arr2 = np.array([[7,8,9],[10,11,12]])
print(np.concatenate([arr1,arr2],axis=0))  #沿0轴合并  沿各个行(y轴方向) 默认情况下axis=0  返回副本
print(np.concatenate([arr1,arr2],axis=1))  #沿1轴合并  沿各个列(x轴方向) 返回副本

对于常见的连接操作,NumPy还提供一些比较方便的方法,如hstack和vstack:

[code]print(np.vstack((arr1,arr2)))  #沿轴0 沿各个行的方向(y轴方向,竖直方向) 返回副本
print(np.hstack((arr1,arr2)))  #沿轴1 沿各个列的方向(x轴方向,水平方向) 返回副本

与此相反split函数用于将一个数组沿指定的轴在指定的位置拆分为多个数组:

[code]arr = np.random.randn(5,2)
print(arr)
first,second,third = np.split(arr,[1,3],axis=0)  #沿0轴  在索引1和3位置进行切割
print("-----------")
print(first)
print("-----------")
print(second)
print("-----------")
print(third)
print("------------")
first,second = np.split(arr,[1],axis=1)  #沿1轴  在索引1位置进行切割
print("-----------")
print(first)
print("-----------")
print(second)

下表列出了所有有关数组连接和拆分的函数:

堆叠辅助类:r_和c_

NumPy命名空间中有两个特殊的对象r_和c_,他们可以使数组的堆叠操作更为简洁:

[code]arr = np.arange(6)
arr1 = arr.reshape((3,2))
arr2 = np.random.randn(3,2)
print(np.r_[arr1,arr2])       #沿轴0  沿各个行的顺序(竖直,y方向)  面向各个行   返回副本
print(np.c_[np.r_[arr1,arr2],arr])  #沿轴1  沿各个列的顺序(水平,x方向)  面向各个列  返回副本

还可以把切片转换为数组:

[code]print(np.c_[1:6,-10:-5])

np.c_堆叠数组时(一个2维数组和一个1维数组,或两个一维数组进行堆叠时),会把一维数组转换为2维列向量(2维数组)再进行合并。

5.元素的重复操作:tile/repeat

对数组进行重复以产生更大数组主要使用tile/repeat两个函数:

repeat会将数组中的各个元素重复一定次数,产生一个更大的数组:

[code]arr = np.arange(3)
print(arr)
print(arr.repeat(3)) #arr中的每个元素都重复3次

和其他流行的数组编程语言如Matlab不同,NumPy中很少需要对数组进行重复,因为NumPy支持广播,能够更好的满足该要求,不同大小的数组间也是可以根据广播规则直接运算的。

默认情况下,如果传入一个整数,则各个元素就会重复那么多次。如果传入的是一组整数,则各个元素就可以重复不同的次数:

[code]print(arr)
print(arr.repeat([2,3,4]))

对于多维数组,还可以让他们的元素沿指定轴重复:

[code]arr = np.random.randn(2,2)
print(arr)
print(arr.repeat(2,axis=0))  #沿轴0(沿各个行) 每个元素重复2次

注意如果没有设置轴向,则数组会被扁平化,可能不是你期望的:

[code]arr = np.random.randn(2,2)
print(arr)
print(arr.repeat(2))

同样对于多维数组进行重复时,也可以传入一组整数,这样会使各切片重复不同的次数:

[code]print(arr)
print(arr.repeat([2,3],axis=0))
print(arr.repeat([2,4],axis=1))

tile的功能是沿指定轴向堆叠数组的副本,可以形象地想象为“铺瓷砖”:

[code]print(arr)
print(np.tile(arr,2))  #第2个参数是一个标量时  表示沿轴1/水平方向(各个列)进行重复堆叠
print(np.tile(arr,(2,1))) #第2个参数也可以是一个元组 表示沿每个轴的重复堆叠次数  第一个元素沿轴0次数 依次类推
print(np.tile(arr,(3,2)))

注意tile和repeat的区别,tile是将数组整体沿指定的轴进行重复堆叠;repeat是将数组中的每个元素/每行/每列分别沿指定的轴进行重复堆叠。2者都返回数组的副本。

 

 

 

 

 

 

 

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: