合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
# numpy练习2:常用函数(numpy和ndarray的属性和方法) ```python import numpy ``` 以下示例均使用矩阵演示,不考虑高阶矩阵的情况。 ## ravel(ndarray) ravel将numpy数组展开成一维形式,并返回新的对象,新对象是原对象的一个视图,对arr2的修改同样会作用到arr1上。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8]]) arr2=arr1.ravel() print(arr1) print() print(arr2) print() print(id(arr2.base)==id(arr1)) ``` [[0 1 2] [3 4 5] [6 7 8]] [0 1 2 3 4 5 6 7 8] True ## flatten(ndarray) flatten与ravel函数相同,但flatten返回原对象的拷贝,修改新对象不会影响原对象的值。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8]]) arr2=arr1.flatten() print(arr1) print() print(arr2) print() print(id(arr2.base)==id(arr1)) ``` [[0 1 2] [3 4 5] [6 7 8]] [0 1 2 3 4 5 6 7 8] False ## reshape(ndarray) reshape用来重新设置矩阵的形状,需要保证变形前后元素个数相等。reshape不影响原对象的形状(shape),而是产生一个新的对象,新对象是原对象的一个视图。**直接设置shape并不会返回新的对象,而是直接修改原对象的形状,这点与reshape不同。** ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) print(arr1) print() arr2=arr1.reshape([2,6]) print(arr2) print() print(id(arr2.base)==id(arr1)) ``` [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]] True ## transpose(ndarray) 进行矩阵转置,返回原矩阵的一个视图。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) print(arr1) print() arr2=arr1.transpose() print(arr2) print() print(id(arr2.base)==id(arr1)) ``` [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] [[ 0 3 6 9] [ 1 4 7 10] [ 2 5 8 11]] True ## resize(ndarray) resize方法直接修改原数组的大小,没有返回值。并且resize不要求调整后的矩阵元素数量多少与原来的相同,若原来的元素不足则用默认值补齐,若原来的元素多余,则舍弃多余的。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) print(arr1) print() arr2=arr1.resize([2,6]) print(arr2) print() print(arr1) print() arr1.resize([1,2]) print(arr1) print() arr1.resize([5,5]) print(arr1) print() ``` [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] None [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]] [[0 1]] [[0 1 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]] ​ ## stack函数(numpy) stack一类的函数用于将多个矩阵连接成一个矩阵。 ### vstack vstack是将多个矩阵在垂直方向按顺序叠加形成新的矩阵。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) arr2=arr1.copy()+100 arr3=numpy.vstack([arr1,arr2]) print("\narr1:\n",arr1) print("\narr2:\n",arr2) print("\narr1和arr2的vstack:\n",arr3) ``` arr1: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] arr2: [[100 101 102] [103 104 105] [106 107 108] [109 110 111]] arr1和arr2的vstack: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11] [100 101 102] [103 104 105] [106 107 108] [109 110 111]] ## hstack hstack是将多个矩阵在水平方向上并置,形成一个新的矩阵。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) arr2=arr1.copy()+100 arr3=numpy.hstack([arr1,arr2]) print("\narr1:\n",arr1) print("\narr2:\n",arr2) print("\narr1和arr2的hstack:\n",arr3) ``` arr1: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] arr2: [[100 101 102] [103 104 105] [106 107 108] [109 110 111]] arr1和arr2的hstack: [[ 0 1 2 100 101 102] [ 3 4 5 103 104 105] [ 6 7 8 106 107 108] [ 9 10 11 109 110 111]] ## dstack dstack使得合成的新对象的维度+1,它将所有参数的最低一维合并,要求其他维度大小相等。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) arr2=arr1.copy()+100 arr3=numpy.dstack([arr1,arr2]) print("\narr1:\n",arr1) print("\narr2:\n",arr2) print("\narr1和arr2的dstack:\n",arr3) ``` arr1: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] arr2: [[100 101 102] [103 104 105] [106 107 108] [109 110 111]] arr1和arr2的dstack: [[[ 0 100] [ 1 101] [ 2 102]] [[ 3 103] [ 4 104] [ 5 105]] [[ 6 106] [ 7 107] [ 8 108]] [[ 9 109] [ 10 110] [ 11 111]]] ## concatenate concatenate用来通用地连接矩阵,通过axis参数指定如何合并。 ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) arr2=arr1.copy()+100 print("\narr1:\n",arr1) print("\narr2:\n",arr2) arr3=numpy.concatenate([arr1,arr2],axis=0) print("\narr1和arr2的在第0维度上的连接:\n",arr3) arr4=numpy.concatenate([arr1,arr2],axis=1) print("\narr1和arr2的在第1维度上的连接:\n",arr4) ``` arr1: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] arr2: [[100 101 102] [103 104 105] [106 107 108] [109 110 111]] arr1和arr2的在第0维度上的连接: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11] [100 101 102] [103 104 105] [106 107 108] [109 110 111]] arr1和arr2的在第1维度上的连接: [[ 0 1 2 100 101 102] [ 3 4 5 103 104 105] [ 6 7 8 106 107 108] [ 9 10 11 109 110 111]] 可以用concatenate来实现任意axis的连接,在哪个维度连接,哪个维度的大小就会发生变化,但无法实现与dstack相似的功能。此外还有row_stack和colunm_stack,row_stack效果等同于vstack,column_stack效果等同于hstack; ## split函数(numpy) split函数用于将一个矩阵拆分成若干个矩阵。如果传入参数是单个数字,那么split函数会将原来的矩阵等分(不能等分的会显示错误);如果传入的是一个数组`[a1, a2, ... an]`,那么将会产生n+1个数组,他们分别是原数组在相应维度上的切片如`x[0:a1]`、`x[a2:a3]`、`x[an:]`,具体的可以查看vsplit的示例。 ### hsplit ```python arr1=numpy.array([[0,1,2] ,[3,4,5] ,[6,7,8] ,[9,10,11]]) arr2=arr1.copy()+100 arr3=numpy.hstack([arr1,arr2]) print(arr3) arr41,arr42=numpy.hsplit(arr3,2) print(arr41) print(arr42) ``` [[ 0 1 2 100 101 102] [ 3 4 5 103 104 105] [ 6 7 8 106 107 108] [ 9 10 11 109 110 111]] [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] [[100 101 102] [103 104 105] [106 107 108] [109 110 111]] ### vsplit ```python arr1=numpy.arange(12).reshape(4,3) arr2=arr1.copy()+100 arr3=numpy.hstack([arr1,arr2]) print(arr3) arr4s=numpy.vsplit(arr3,[1,3]) for arr in arr4s: print() print(arr) ``` [[ 0 1 2 100 101 102] [ 3 4 5 103 104 105] [ 6 7 8 106 107 108] [ 9 10 11 109 110 111]] [[ 0 1 2 100 101 102]] [[ 3 4 5 103 104 105] [ 6 7 8 106 107 108]] [[ 9 10 11 109 110 111]] ### dsplit ```python arr1=numpy.arange(12).reshape(4,3) arr2=arr1.copy()+100 arr3=numpy.hstack([arr1,arr2]) arr4=numpy.array([arr3]) print(arr4) arr5s=numpy.dsplit(arr4,[1,4]) for arr in arr5s: print() print(arr) ``` [[[ 0 1 2 100 101 102] [ 3 4 5 103 104 105] [ 6 7 8 106 107 108] [ 9 10 11 109 110 111]]] [[[0] [3] [6] [9]]] [[[ 1 2 100] [ 4 5 103] [ 7 8 106] [ 10 11 109]]] [[[101 102] [104 105] [107 108] [110 111]]] dsplit将矩阵在第3个维度上进行拆分。注意当矩阵维度大于3维时也拆分第3维。 numpy主要的处理对象仍是矩阵,将**矩阵的高3维(0,1,2维度)看作三维空间的竖直方向(vertical)、水平方向(horizontal)和深度方向(depth)**,可以用split函数更为通用地处理分割任务。 ### split ```python arr1=numpy.arange(12).reshape(4,3) arr2=arr1.copy()+100 arr3=numpy.hstack([arr1,arr2]) print("arr3:\n",arr3) arr4=numpy.array([arr3]) print("\narr4:\n",arr4) arr5s=numpy.split(arr3,2,axis=0) print("\narr5s:") for arr in arr5s: print(arr) arr6s=numpy.split(arr3,[1,4],axis=1) print("\narr6s:") for arr in arr6s: print(arr) arr7s=numpy.split(arr4,2,axis=2) print("\narr7s:") for arr in arr7s: print(arr) ``` arr3: [[ 0 1 2 100 101 102] [ 3 4 5 103 104 105] [ 6 7 8 106 107 108] [ 9 10 11 109 110 111]] arr4: [[[ 0 1 2 100 101 102] [ 3 4 5 103 104 105] [ 6 7 8 106 107 108] [ 9 10 11 109 110 111]]] arr5s: [[ 0 1 2 100 101 102] [ 3 4 5 103 104 105]] [[ 6 7 8 106 107 108] [ 9 10 11 109 110 111]] arr6s: [[0] [3] [6] [9]] [[ 1 2 100] [ 4 5 103] [ 7 8 106] [ 10 11 109]] [[101 102] [104 105] [107 108] [110 111]] arr7s: [[[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]]] [[[100 101 102] [103 104 105] [106 107 108] [109 110 111]]] ## tolist(ndarray) tolist方法能够将ndarray对象转化为python标准的list对象。 ```python arr1=numpy.arange(12).reshape(4,3) print(type(arr1)) print(arr1) arr2=arr1.tolist() print() print(type(arr2)) print(arr2) ``` <class 'numpy.ndarray'> [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] <class 'list'> [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]] ## astype(ndarray) astype将已有的ndarray对象中的元素类型转换为指定类型,并返回一个新的对象。 ```python arr1=numpy.arange(12).reshape(4,3) print(arr1) arr2=arr1.astype(numpy.complex) print(arr2) ``` [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] [[ 0.+0.j 1.+0.j 2.+0.j] [ 3.+0.j 4.+0.j 5.+0.j] [ 6.+0.j 7.+0.j 8.+0.j] [ 9.+0.j 10.+0.j 11.+0.j]] ## savetxt(numpy) ```python arr1=numpy.arange(12).reshape(4,3) print(arr1) numpy.savetxt("tmp.txt",arr1) ``` [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] tmp.txt中的内容如图所示![](figs\1.png) ## loadtxt(numpy) loadtxt可以用来读取savetxt存储的文件。 ```python arr1=numpy.loadtxt("tmp.txt") print(arr1) ``` [[ 0. 1. 2.] [ 3. 4. 5.] [ 6. 7. 8.] [ 9. 10. 11.]] 除此之外,loadtxt也可以用来加载csv文件,使用delimiter来指定csv文件的分隔符。 ## average(numpy) average可以用计算一个矩阵的各个元素的加权平均值(通过weights参数来指定权值向量,可以通过axis来指定要计算的维度)。当weights不指定时计算算术平均数,当axis不指定时计算整个矩阵,可以同时指定多个维度。 ```python arr1=numpy.random.random([3,3]) print(arr1) weights1=numpy.arange(3) weights2=numpy.arange(9).reshape([3,3]) print("\nweights1:\n",weights1) print("\nweights2:\n",weights2) print("\nCase1:两者shape完全相同且不指定计算轴,计算所有数值的平均") ans=numpy.average(arr1,weights=weights2) print(ans) print("\nCase2:两者shape完全相同且指定计算轴,计算这个轴向上所有数值的平均") ans=numpy.average(arr1,weights=weights2,axis=0) print(ans) print("\nCase3:两者shape不同,此时要求weights是向量,且长度等于计算轴上的元素多少") ans=numpy.average(arr1,weights=weights1,axis=1) print(ans) print("\nCase4:不指定weights和axis,计算所有数的算术平均数") ans=numpy.average(arr1) print(ans) print("\nCase5:不指定weights,但指定axis,计算计算轴上的的算术平均数") ans=numpy.average(arr1,axis=(0,1)) print(ans) ``` [[0.8993591 0.47355828 0.32534926] [0.99134123 0.2627845 0.53112088] [0.48290455 0.50547859 0.45758421]] weights1: [0 1 2] weights2: [[0 1 2] [3 4 5] [6 7 8]] Case1:两者shape完全相同且不指定计算轴,计算所有数值的平均 0.49726316634293993 Case2:两者shape完全相同且指定计算轴,计算这个轴向上所有数值的平均 [0.65238345 0.42192053 0.46446511] Case3:两者shape不同,此时要求weights是向量,且长度等于计算轴上的元素多少 [0.37475227 0.44167542 0.473549 ] Case4:不指定weights和axis,计算所有数的算术平均数 0.5477200664361863 Case5:不指定weights,但指定axis,计算计算轴上的的算术平均数 0.5477200664361863 ## max(numpy) 求最大值,同样可以指定axis。 ```python arr1=numpy.random.random([3,3]) print(arr1) print("\n整个矩阵中最大的元素:") ans=numpy.max(arr1) print(ans) print("\n每一列所有行的最大元素:") ans=numpy.max(arr1,axis=0) print(ans) ``` [[0.47586685 0.37421012 0.08462522] [0.97685016 0.88731492 0.49075314] [0.85798507 0.40270191 0.93738027]] 整个矩阵中最大的元素: 0.9768501588770301 每一列所有行的最大元素: [0.97685016 0.88731492 0.93738027] ## min(numpy) 求最小值,用法用numpy.max ## ptp(numpy) 求极差,用法同numpy.max ```python arr1=numpy.random.random([3,3]) print(arr1) print("\n整个矩阵的极差:") ans=numpy.ptp(arr1) print(ans) ``` [[0.93852342 0.87264888 0.00956858] [0.5940792 0.77692926 0.84618922] [0.40332324 0.73116715 0.10482852]] 整个矩阵的极差: 0.9289548467063062 ## median(numpy) 求中位数,用法同numpy.max ```python arr1=numpy.random.random([3,3]) print(arr1) print("\n整个矩阵的极差:") ans=numpy.median(arr1) print(ans) ``` [[0.85846578 0.64713455 0.04945136] [0.59845135 0.38586531 0.12984422] [0.64009235 0.01108018 0.24574814]] 整个矩阵的极差: 0.38586531089439835 ## var(numpy) 求方差,用法同numpy.max ```python arr1=numpy.random.random([3,3]) print(arr1) print("\n整个矩阵的方差:") ans=numpy.var(arr1) print(ans) ``` [[0.18943536 0.07676954 0.91427832] [0.5504432 0.03056685 0.36502979] [0.0282473 0.81213967 0.99060445]] 整个矩阵的方差: 0.1351450515174477 ## std(numpy) 求标准差,用法同numpy.std ```python arr1=numpy.random.random([3,3]) print(arr1) print("\n整个矩阵的标准差:") ans=numpy.std(arr1) print(ans) ``` [[0.15446601 0.96282174 0.60415276] [0.04446096 0.83565483 0.84943249] [0.54312218 0.83132801 0.33746839]] 整个矩阵的标准差: 0.31197497991584405 ## diff(numpy) 返回参数的相邻元素的差值构成的向量`[a2-a1,a3-a2,...]`,新的数组具有n-1个元素。 ```python arr1=numpy.arange(3) arr2=numpy.diff(arr1) print(arr2) ``` [1 1] ## log(numpy) 求参数的自然对数。 ```python arr1=numpy.arange(3)+1 arr2=numpy.log(arr1) print(arr2) ``` [0. 0.69314718 1.09861229] ## where(numpy) 返回符合条件的数组元素的下标。 ```python arr1=numpy.arange(9).reshape([3,3]) xindex,yindex=numpy.where(arr1>6) print(xindex) print(yindex) ``` [2 2] [1 2] ## take(numpy) take函数可以根据索引值来获取对应的元素组成数组。 ```python arr1=numpy.arange(9) indexs=numpy.where(arr1>2) arr2=numpy.take(arr1,indexs) print(arr2) ``` [[3 4 5 6 7 8]] 但是take使用的索引值只能是一维的,请看下面代码 ```python arr1=numpy.arange(9).reshape(3,3) arr1[0,1]=100 print(arr1) indexs=numpy.where(arr1>2) print(indexs) arr2=numpy.take(arr1,indexs) print(arr2) ``` [[ 0 100 2] [ 3 4 5] [ 6 7 8]] (array([0, 1, 1, 1, 2, 2, 2], dtype=int64), array([1, 0, 1, 2, 0, 1, 2], dtype=int64)) [[ 0 100 100 100 2 2 2] [100 0 100 2 0 100 2]] 上面代码的结果并不是我们预期的结果,这是因为take函数将indexs中的每个数字都看作一个独立的下标而非二维数组的下标。由此可以见,无法使用take来进行二维和高维数组元素的筛选。要选择高维数组的指定元素,可以直接使用下标获取,请看下例: ```python arr1=numpy.arange(9).reshape(3,3) indexs=numpy.where(arr1>2) arr2=arr1[indexs] print(arr2) ``` [3 4 5 6 7 8] ## argmin(numpy) 返回最小元素的索引(默认为flat模式下的下标)。 ```python arr1=numpy.arange(9).reshape(3,3) ans=numpy.argmin(arr1) print(ans) ``` 0 ## argmax(numpy) 返回最大元素的索引(默认为flat模式下的下标)。 ```python arr1=numpy.arange(9).reshape(3,3) ans=numpy.argmax(arr1) print(ans) ``` 8 ## unravel_index(numpy) 将flat索引转化为矩阵索引。 ```python arr1=numpy.arange(9).reshape(3,3) flat_ans=numpy.argmax(arr1) ans=numpy.unravel_index(flat_ans,arr1.shape) print(ans) print(arr1[ans]) ``` (2, 2) 8 ## convolve(numpy) 计算向量a和b的卷积。 ```python a=numpy.ones([5]) b=numpy.arange(6) c=numpy.convolve(a,b) print(a) print(b) print(c) ``` [1. 1. 1. 1. 1.] [0 1 2 3 4 5] [ 0. 1. 3. 6. 10. 15. 14. 12. 9. 5.] ## exp(numpy) 求给定元素的自然指数结果。 ```python a=numpy.arange(5) b=numpy.exp(a) print(a) print(b) print() c=numpy.random.random([5,5]) d=numpy.exp(c) print(c) print(d) ``` [0 1 2 3 4] [ 1. 2.71828183 7.3890561 20.08553692 54.59815003] [[0.54416621 0.60281522 0.35765644 0.57887768 0.56960679] [0.51770127 0.78675766 0.5772893 0.28937978 0.86039869] [0.34440243 0.96048522 0.90621318 0.28729379 0.14745599] [0.3990738 0.92288426 0.82812327 0.6094874 0.22356079] [0.25612473 0.1956747 0.05881144 0.95180227 0.81285925]] [[1.72317101 1.8272557 1.42997425 1.78403504 1.76757189] [1.67816556 2.19626384 1.78120358 1.33559887 2.36410306] [1.41114641 2.61296402 2.47493264 1.33281573 1.15888228] [1.49044361 2.51653829 2.28901885 1.83948823 1.25052166] [1.29191386 1.21613124 1.06057524 2.59037401 2.2543445 ]] ## linspace(numpy) linspace(a,b,c)返回在a和b之间平均分布的c个数(包含a和b) ```python print(numpy.linspace(1,10,9)) ``` [ 1. 2.125 3.25 4.375 5.5 6.625 7.75 8.875 10. ] ## fill(ndarray) 将矩阵中的所有元素都填充指定的数。 ```python a=numpy.random.random([5,5]) print(a) a.fill(1) print(a) ``` [[0.35040125 0.93582284 0.70121339 0.19035895 0.71265932] [0.89663449 0.10066004 0.39664671 0.95030878 0.05526574] [0.09644127 0.13623986 0.4750009 0.87189624 0.19931902] [0.36584705 0.85217281 0.12167366 0.60530817 0.78776323] [0.97713236 0.07414655 0.31971706 0.32728158 0.0945021 ]] [[1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.]]