Python数据分析numpy库
1.简介
Numpy库是进行数据分析的基础库,panda库就是基于Numpy库的,在计算多维数组与大型数组方面使用最广,还提供多个函数操作起来效率也高
2.Numpy库的安装
linux(Ubuntu和debian)下:sudo apt-get install python-numpy
linux(fedora)下:sudo yum install numpy scipy
conda isntall numpy
3.ndarray,numpy的核心
1 array方法下的几个属性 2 >>> a=np.array([1,2,3]) 3 >>> a 4 array([1, 2, 3]) 5 >>> type(a) 6 <class 'numpy.ndarray'> 7 >>> a.dtype 8 dtype('int32') 9 >>> a.ndim 10 1 11 >>> a.size 12 3 13 >>> a.shape 14 (3,) 15 >>> a.itemsize 16 4
3,如何创建数组
1 >>> c=np.array([[1,2,3],[4,5,6]]) 列表为参数 2 >>> c 3 array([[1, 2, 3], 4 [4, 5, 6]]) 5 >>> c=np.array(((1,2,3),(4,5,6))) 元组也可以作为参数 6 >>> c 7 array([[1, 2, 3], 8 [4, 5, 6]])
在创建数组的时候也可以指定类型,常用 都有int-,int8,int16,int32,int64,float_,float16,32,64,uint8,16,32,64
1 >>> c=np.array([[1,2,3],[4,5,6]],dtype=complex) 2 >>> c 3 array([[ 1.+0.j, 2.+0.j, 3.+0.j], 4 [ 4.+0.j, 5.+0.j, 6.+0.j]]) 5 >>> c.dtype 6 dtype('complex128') 7 >>> c.dtype.name 8 'complex128'
自带的数组创建方法
>>> np.zeros((3,3)) array([[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) >>> np.ones((3,3)) array([[ 1., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]]) >>> np.arange(0,10) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.arange(0,12,3) array([0, 3, 6, 9]) >>> np.arange(0,4,0.6) array([ 0. , 0.6, 1.2, 1.8, 2.4, 3. , 3.6]) >>> np.arange(0,12).reshape(3,4) array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> np.linspace(0,10,5) array([ 0. , 2.5, 5. , 7.5, 10. ]) >>> np.random.random(6) array([ 0.90252601, 0.85271104, 0.17201238, 0.9884257 , 0.74112411, 0.28453949]) >>> np.random.random((3,3)) array([[ 0.98041444, 0.40374122, 0.1174572 ], [ 0.8121098 , 0.24770467, 0.9823125 ], [ 0.22909469, 0.96560959, 0.47319287]])
4.说完了数组的创建方法,下面讲下数组的计算方法
1 >>> a=np.arange(4) 2 >>> a 3 array([0, 1, 2, 3])
算术运算符 4 >>> a+4 5 array([4, 5, 6, 7]) 6 >>> a*2 7 array([0, 2, 4, 6]) 8 >>> a 9 array([0, 1, 2, 3]) 10 >>> a*a 11 array([0, 1, 4, 9]) 12 >>> b=np.arange(4,8) 13 >>> b 14 array([4, 5, 6, 7]) 15 >>> a*np.sin(b) 16 array([-0. , -0.95892427, -0.558831 , 1.9709598 ]) 17 >>> a*np.sqrt(b) 18 array([ 0. , 2.23606798, 4.89897949, 7.93725393])
矩阵相乘 19 >>> A=np.arange(9).reshape(3,3) 20 >>> A 21 array([[0, 1, 2], 22 [3, 4, 5], 23 [6, 7, 8]]) 24 >>> B=np.ones((3,3)) 25 >>> B 26 array([[ 1., 1., 1.], 27 [ 1., 1., 1.], 28 [ 1., 1., 1.]]) 29 >>> A*B 30 array([[ 0., 1., 2.], 31 [ 3., 4., 5.], 32 [ 6., 7., 8.]]) 33 >>> np.dot(A,B) 34 array([[ 3., 3., 3.], 35 [ 12., 12., 12.], 36 [ 21., 21., 21.]]) 37 >>> A 38 array([[0, 1, 2], 39 [3, 4, 5], 40 [6, 7, 8]]) 41 >>> a 42 array([0, 1, 2, 3])
自增自减运算符 43 >>> a+=4 44 >>> a 45 array([4, 5, 6, 7]) 46 >>> a*=2 47 >>> a 48 array([ 8, 10, 12, 14])
通用函数 49 >>> np.sin(a) 50 array([ 0.98935825, -0.54402111, -0.53657292, 0.99060736]) 51 >>> np.sqrt(a) 52 array([ 2.82842712, 3.16227766, 3.46410162, 3.74165739]) 53 >>> np.log(a) 54 array([ 2.07944154, 2.30258509, 2.48490665, 2.63905733])
聚合函数
55 >>> a.sum() 56 44 57 >>> a.min() 58 8 59 60 >>> a.max() 61 14 62 >>> a.mean() 63 11.0 64 >>> a.std() 65 2.2360679774997898 66 >>>
5.索引机制,切片和迭代方法
1)索引机制
1 >>> np.arange(9) 2 array([0, 1, 2, 3, 4, 5, 6, 7, 8]) 一维数组根据索引取数 3 >>> a=np.arange(9) 4 >>> a[2] 5 2 6 >>> a[[2,3,4]] 7 array([2, 3, 4]) 8 >>> A=np.arange(10,19).reshape((3,3)) 9 >>> A 10 array([[10, 11, 12], 矩阵根据索引取数 11 [13, 14, 15], 12 [16, 17, 18]]) 13 >>> A[1,2] 14 15 15 >>> A[[1,2],[2,2]] 16 array([15, 18])
2)切片操作(所谓切片,就是用冒号隔开的数字置于方括号里)
1 >>> a=np.arange(10,16) 一维数组的切片操作 2 >>> a 3 array([10, 11, 12, 13, 14, 15]) 4 >>> a[1:5] 5 array([11, 12, 13, 14]) 6 >>> a[1:5:2] 7 array([11, 13]) 8 >>> a[::2] 9 array([10, 12, 14]) 10 >>> a[:5:2] 11 array([10, 12, 14]) 12 >>> a[:5:] 13 array([10, 11, 12, 13, 14])
二维数组矩阵的切片
1 >>> A=np.arange(10,19).reshape((3,3)) 2 >>> A[0,:] 3 array([10, 11, 12]) 4 >>> A 5 array([[10, 11, 12], 6 [13, 14, 15], 7 [16, 17, 18]]) 8 >>> A[:,0] 9 array([10, 13, 16]) 10 >>> A[0:2,0:2] 行列的切片 11 array([[10, 11], 12 [13, 14]]) 13 >>> A[[0,2],0:2] 行,或列的不连续切片 14 array([[10, 11], 15 [16, 17]])
6数组的遍历方法
1 >>> for i in a: 2 print(i) 3 4 5 10 6 11 7 12 8 13 9 14 10 15 11 >>> for row in A: 12 print(row) 13 14 15 [10 11 12] 16 [13 14 15] 17 [16 17 18] 18 >>> for item in A.flat: 19 print(item) 20 21 22 10 23 11 24 12 25 13 26 14 27 15 28 16 29 17 30 18 31 >>> np.apply_along_axis(np.mean,axis=0,arr=A) 更优雅的迭代方法,应用自定义函数 32 array([ 13., 14., 15.]) 33 >>> np.apply_along_axis(np.mean,axis=1,arr=A) 34 array([ 11., 14., 17.]) 35 >>> def foo(x): 36 return x/2 37 38 >>> np.apply_along_axis(foo,axis=1,arr=A) 39 array([[ 5. , 5.5, 6. ], 40 [ 6.5, 7. , 7.5], 41 [ 8. , 8.5, 9. ]])
7.对数组的的元素应用条件,返回boolean值
1 >>> A=np.random.random((4,4)) 2 >>> A 3 array([[ 0.70709738, 0.80240902, 0.94803025, 0.98312311], 4 [ 0.07900716, 0.93118649, 0.75250378, 0.35555096], 5 [ 0.66154306, 0.96191193, 0.15286704, 0.44050484], 6 [ 0.87358818, 0.23117656, 0.59518599, 0.58695854]]) 7 >>> A<0.5 8 array([[False, False, False, False], 9 [ True, False, False, True], 10 [False, False, True, True], 11 [False, True, False, False]], dtype=bool) 12 >>> A[A<0.5] 13 array([ 0.07900716, 0.35555096, 0.15286704, 0.44050484, 0.23117656])
8.我们可以通过reape()方法来改变以为数组的形状,也可以通过修改shape这个属性字段来修改
>>> a array([ 0.70290611, 0.79908059, 0.67798575, 0.67487014, 0.77510071, 0.87493472, 0.25405607, 0.38421272, 0.05605654, 0.14063901, 0.11186545, 0.76120191]) >>> a.shape=(3,4) >>> a array([[ 0.70290611, 0.79908059, 0.67798575, 0.67487014], [ 0.77510071, 0.87493472, 0.25405607, 0.38421272], [ 0.05605654, 0.14063901, 0.11186545, 0.76120191]]) >>> a.shape (3, 4) >>> a=a.ravel() >>> a array([ 0.70290611, 0.79908059, 0.67798575, 0.67487014, 0.77510071, 0.87493472, 0.25405607, 0.38421272, 0.05605654, 0.14063901, 0.11186545, 0.76120191]) >>> a.shape=(12) >>> a array([ 0.70290611, 0.79908059, 0.67798575, 0.67487014, 0.77510071, 0.87493472, 0.25405607, 0.38421272, 0.05605654, 0.14063901, 0.11186545, 0.76120191]) >>> A array([[ 0.70709738, 0.80240902, 0.94803025, 0.98312311], [ 0.07900716, 0.93118649, 0.75250378, 0.35555096], [ 0.66154306, 0.96191193, 0.15286704, 0.44050484], [ 0.87358818, 0.23117656, 0.59518599, 0.58695854]]) >>> A.transpose() 矩阵的转置函数 array([[ 0.70709738, 0.07900716, 0.66154306, 0.87358818], [ 0.80240902, 0.93118649, 0.96191193, 0.23117656], [ 0.94803025, 0.75250378, 0.15286704, 0.59518599], [ 0.98312311, 0.35555096, 0.44050484, 0.58695854]]) >>>
9.数组的连接,1)上下对接2)左右对接 原理是运用了栈这个概念,一个是水平栈,一个是垂直栈,有两种方法,一个是vstack,hstack,另一个是column_stack,row_stack
1 >>> A=np.zeros((3,3)) 2 >>> B=np.ones((3,3)) 3 >>> np.vstack((A,B)) 4 array([[ 0., 0., 0.], 5 [ 0., 0., 0.], 6 [ 0., 0., 0.], 7 [ 1., 1., 1.], 8 [ 1., 1., 1.], 9 [ 1., 1., 1.]]) 10 >>> np.hstack((A,B)) 11 array([[ 0., 0., 0., 1., 1., 1.], 12 [ 0., 0., 0., 1., 1., 1.], 13 [ 0., 0., 0., 1., 1., 1.]]) 14 >>> np.column_stack((A,B)) 15 array([[ 0., 0., 0., 1., 1., 1.], 16 [ 0., 0., 0., 1., 1., 1.], 17 [ 0., 0., 0., 1., 1., 1.]]) 18 >>> np.row_stack ((A,B)) 19 array([[ 0., 0., 0.], 20 [ 0., 0., 0.], 21 [ 0., 0., 0.], 22 [ 1., 1., 1.], 23 [ 1., 1., 1.], 24 [ 1., 1., 1.]])
9.数组的切分,数组切分其实是数组连接的逆操作
两种方法:1)hsplist(),vsplist() 2)split() 此方法更强大,能指定参数分割成不对称的两个部分
1 >>> A=np.arange(16).reshape((4,4)) 2 >>> A 3 array([[ 0, 1, 2, 3], 4 [ 4, 5, 6, 7], 5 [ 8, 9, 10, 11], 6 [12, 13, 14, 15]]) 7 >>> [B,C]=np.hsplit(A,2) 8 >>> B 9 array([[ 0, 1], 10 [ 4, 5], 11 [ 8, 9], 12 [12, 13]]) 13 >>> C 14 array([[ 2, 3], 15 [ 6, 7], 16 [10, 11], 17 [14, 15]]) 18 >>> [B,C]=np.vsplit(A,2) 19 >>> B 20 array([[0, 1, 2, 3], 21 [4, 5, 6, 7]]) 22 >>> C 23 array([[ 8, 9, 10, 11], 24 [12, 13, 14, 15]]) 25 >>> [A1,A2,A3]=np.split(A,[1,3],axis=1) split函数指定从1,3开始分割,1代表列,0代表行 26 >>> A1 27 array([[ 0], 28 [ 4], 29 [ 8], 30 [12]]) 31 >>> A2 32 array([[ 1, 2], 33 [ 5, 6], 34 [ 9, 10], 35 [13, 14]]) 36 >>> A3 37 array([[ 3], 38 [ 7], 39 [11], 40 [15]]) 41 >>> [A1,A2,A3]=np.split(A,[1,3],axis=0) 42 >>> A1 43 array([[0, 1, 2, 3]]) 44 >>> A2 45 array([[ 4, 5, 6, 7], 46 [ 8, 9, 10, 11]]) 47 >>> A3 48 array([[12, 13, 14, 15]])
10.对象的副本与视图,在numpy库中我们队数组的操作并不会在原来的数组上创建副本,而是得到原来数组的视图,当我们改变原来的数组时,新的数组也会随之发生改变,包括切片也是 ,需要区别的是,Python列表操作得到的是副本,如果想要得到numpy中数组的副本,用copy函数
1 >>> a=np.arange(4) 2 >>> a 3 array([0, 1, 2, 3]) 4 >>> b=a 5 >>> b 6 array([0, 1, 2, 3]) 7 >>> a[0]=1 8 >>> b[0] 9 1 10 >>> c=a.copy() 用copy()来得到副本 11 >>> a 12 array([1, 1, 2, 3]) 13 >>> c 14 array([1, 1, 2, 3]) 15 >>> a[0]=0 16 >>> c 17 array([1, 1, 2, 3]) 18 >>> a 19 array([0, 1, 2, 3])
10.numpy数组的 广播机制(broadcasting)
当两个数组形状不相同时,我们可以用广播机制进行运算,广播机制会自动将数组进行补全
补全规则:1)应用广播机制也是有条件的,需要两个数组在以为条件下等长,如不是,则会抛出异常
2)为缺失的维度补上一个1,如下,将b变成4*1
3)为缺失元素用已有值进行填充,将b变成4个【0,1,2,3】
1 >>> A 2 array([[ 0, 1, 2, 3], 3 [ 4, 5, 6, 7], 4 [ 8, 9, 10, 11], 5 [12, 13, 14, 15]]) 6 >>> b=np.arange(4) 7 >>> A+b 8 array([[ 0, 2, 4, 6], 9 [ 4, 6, 8, 10], 10 [ 8, 10, 12, 14], 11 [12, 14, 16, 18]]) 12 >>>
11。结构化数组
除了一维数组,二维数组,还可以创建更复杂的结构体数组,其中每个元素都是一个结构体,下面阐述下结构体的类型
1 >>> structued=np.array([(1,'first',0.5,1+2j),(2,'second',1.3,2-2j),(3,'third',8.3,4-2j)],dtype=('i2,a6,f4,c8')) 2 >>> structued 3 array([(1, b'first', 0.5 , 1.+2.j), 4 (2, b'second', 1.29999995, 2.-2.j), 5 (3, b'third', 8.30000019, 4.-2.j)], 6 dtype=[('f0', '<i2'), ('f1', 'S6'), ('f2', '<f4'), ('f3', '<c8')]) 对每一列指定元素的名字与类型,相当于关键字 7 >>> structued[1] 8 (2, b'second', 1.29999995, 2.-2.j) 9 >>> structued[2] 10 (3, b'third', 8.30000019, 4.-2.j) 11 >>> structued['f0'] 12 array([1, 2, 3], dtype=int16) 13 >>> structued['f1'] 14 array([b'first', b'second', b'third'], 15 dtype='|S6') 16 >>> structued=np.array([(1,'first',0.5,1+2j),(2,'second',1.3,2-2j),(3,'third',8.3,4-2j)],dtype=[('id','<i2'),('position','a6'),('value','f4'),('complex','c8')]) 17 >>> structued 18 array([(1, b'first', 0.5 , 1.+2.j), 19 (2, b'second', 1.29999995, 2.-2.j), 20 (3, b'third', 8.30000019, 4.-2.j)], 21 dtype=[('id', '<i2'), ('position', 'S6'), ('value', '<f4'), ('complex', '<c8')]) 22 >>> structued.dtype.names 23 ('id', 'position', 'value', 'complex') 24 25 >>> structued['position'] 通过一个关键字来获取所有结构体元素的值 26 array([b'first', b'second', b'third'], 27 dtype='|S6')
12.numpy文件的数据读与写
两种方式1)二进制文件的读与写 2)从文件中读取数据text,csv
1 >>> np.save('c:A',A) 保存到文件中 2 >>> load_data=np.load('c:A.npy') 从文件中读取 ,np模块保存的是二进制数据 3 >>> load_data 4 array([[ 0, 1, 2, 3], 5 [ 4, 5, 6, 7], 6 [ 8, 9, 10, 11], 7 [12, 13, 14, 15]])
>>> data=np.genfromtxt('c:333.csv',delimiter=',',names=True) genfromtxt()这个方法只能读取数字,对于字符串类型的则便成为NAN >>> data array([( 0., nan, 12., nan), ( 1., nan, 24., nan), ( 2., nan, 25., nan)], dtype=[('A', '<f8'), ('add', '<f8'), ('age', '<f8'), ('name', '<f8')]) >>> data['A'] array([ 0., 1., 2.]) >>> data[0] ( 0., nan, 12., nan) >>>