感觉看一遍书,很快,但也忘得快,所以决定把程序和笔记手打出来,一方面可以记得清楚,之后要复习的时候也方便。慢慢来比较快哈。
NumPy 是 Python 科学计算的基础包,其部分功能如下:
- Ndarray,快速高效的多维数组对象
- 直接对数组执行数学运算及对数组执行元素级计算的函数
- 线性代数运算、随机数生成以及傅里叶变换功能
- 将 C、C++、Fortran 代码集成到 Python 的工具
NumPy的ndarry:一种多维数组对象(NumPy最重要的一个特点),该对象是一个快速而灵活的大数据集容器。
ndarry中的所有元素必须是同种类型的,每个数组都有一个shape(一个表示各维度大小的 元组)和一个dtype(一个用于说明数组类型的对象)一、首先创建ndarrayy
方法1:使用array函数
import numpy as np #创建ndarray data1=[6, 7.5, 8, 0, 1] #列表 arr1=np.array(data1) #array函数接受一切序列性的对象 arr1 array([6. , 7.5, 8. , 0. , 1. ]) data2=[[1, 2, 3, 4],[5, 6, 7, 8]] #嵌套序列,二维列表 arr2=np.array(data2) #二维数组 arr2 array([[1, 2, 3, 4], [5, 6, 7, 8]]) arr2.shape (2, 4) arr2.dtype dtype('int32')
方法2:使用一些数组创建函数
如zeros和ones函数分别可以创建指定长度或形状的全0或全1数组,要用它们创建多维数组,只需传入一个表示形状的元组即可:
np.zeros(10) array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) np.zeros((3,6)) array([[0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.]]) np.arange(15) #返回的是ndarray array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) np.ones((3,6),dtype=np.float) array([[1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1.]])
ndarray的数据类型转换
arr1=np.array([1,2,3],dtype=np.float64) arr1.dtype dtype('float64') arr2=np.array([1,2,3],dtype=np.int32) arr2.dtype dtype('int32')
也可以通过ndarray的astype方法显式地转换其dtype:
arr=np.array([1,2,3,4,5]) arr.dtype dtype('int32') float_arr=arr.astype(np.float64) float_arr.dtype dtype('float64')
二、数组和标量之间的运算
数组可以让你不用编写循环即可对数据进行批量运算。这通常叫做矢量化(vectorzation),大小相等的数组之间的任何算术运算都会将运算应用到元素级。
arr=np.array([[1,2,3],[4,5,6]]) arr array([[1, 2, 3], [4, 5, 6]]) arr*arr array([[ 1, 4, 9], [16, 25, 36]]) arr-arr array([[0, 0, 0], [0, 0, 0]]) 1/arr #数组与标量的运算,也会将标量值传播到各个元素 array([[1. , 0.5 , 0.33333333], [0.25 , 0.2 , 0.16666667]])
不同大小的数组之间的运算叫做传播(broadcasting)。
三、基本的索引和切片
NumPy数组的索引是一个丰富的主题,因为选取数据子集或单个元素的方式有很多。(嗯?)
一维数组:
arr=np.arange(10) arr array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) arr[5] 5 arr[5:8] array([5, 6, 7]) arr[5:8]=12 arr array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9]) arr_slice=arr[5:8] arr_slice[1]=12345 arr array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
对于高维度数组:在一个二维数组中,各索引位置上的元素不再是标量而是一维数组:
arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]]) arr2d[2] array([7, 8, 9]) arr2d[0][2] #对单个元素进行递归访问 3 arr2d[0,2] 3
在多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray(它含有高一维度上的所有数据),因此在2*2*3数组arr3d中:
arr3d=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) arr3d array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]]) arr3d[0] #2*3数组 array([[1, 2, 3], [4, 5, 6]])
标量值和数组都可赋值给arr3d[0]:
切片索引
对于二维数组,可以看出切片是沿着一个轴向选取元素。一次可以传入多个切片,就像传入索引那样。
arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]]) arr2d array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) arr2d[:2] #这种是切片 array([[1, 2, 3], [4, 5, 6]]) arr2d[:2,1:] array([[2, 3], [5, 6]]) arr2d[1,:2] array([4, 5]) arr2d[2,:1] array([7]) arr2d[:,:1] #只有冒号,表示选取整个轴 array([[1], [4], [7]]) arr2d[:2,1:]=0 #对切片赋值 arr2d array([[1, 0, 0], [4, 0, 0], [7, 8, 9]])
四、数组转置和轴对换
转置(transpose)是重塑的一种特殊形式,它返回的是源数据的视图???(不会进行任何复制操作)
1.特殊的T属性 (简单的转置使用,就相当于进行轴对换)
arr=np.arange(15).reshape((3,5)) arr array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) arr.T array([[ 0, 5, 10], [ 1, 6, 11], [ 2, 7, 12], [ 3, 8, 13], [ 4, 9, 14]]) arr=np.random.randn(6,3) np.dot(arr.T,arr) #np.dot计算矩阵內积XTX array([[ 4.73440561, -1.80831405, 1.97638433], [-1.80831405, 6.76842567, -2.01967333], [ 1.97638433, -2.01967333, 1.69620536]])
2.transpose
对于高维数组,transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置。(有点难理解)
取个例子如下:
arr=np.arange(16).reshape((2,2,4)) arr array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) arr.transpose((1,0,2)) array([[[ 0, 1, 2, 3], [ 8, 9, 10, 11]], [[ 4, 5, 6, 7], [12, 13, 14, 15]]]) arr.transpose((1,2,0)) array([[[ 0, 8], [ 1, 9], [ 2, 10], [ 3, 11]], [[ 4, 12], [ 5, 13], [ 6, 14], [ 7, 15]]])
arr.transpose((1,0,2))的1,0,2三个数分别代表shape()的三个数的顺序,初始的shape是(2,2,4),也就是2维的2 x 4矩阵,索引分别是shape的[0],[1],[2],arr.transpose((1,0,2))之后,我们的索引就变成了shape[1][0][2],对应shape值是shape(2,2,4),所以矩阵形状不变;arr.transpose((1,2,0))之后,我们的索引就变成了shape[1][2][0],对应shape值是shape(2,4,2),即2维的2 x 4矩阵,比如转置前4的索引为(0,1,0),arr.transpose((1,0,2))之后为(1,0,0)
3.多维数组,还有个swapaxes方法,它只需接受一对轴编号。此时还是对shape索引进行更改。
arr=np.arange(16).reshape((2,2,4)) arr array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) arr.swapaxes(1,2) #shape[1][2]位置互换,即变换之前4的索引为(0,1,0),swapaxes(1,2)之后为(0,0,1) array([[[ 0, 4], [ 1, 5], [ 2, 6], [ 3, 7]], [[ 8, 12], [ 9, 13], [10, 14], [11, 15]]])