下面的内容是根据李老师在B站上的课程总结的,主要用于自己复习回顾 这一篇是接着上一篇《python学习3-文件、面向对象等》的
48、nadarray的输出形式跟列表类似,但是不同,是两种不同的数据对象
import numpy as np values = [20.1,20.8,21.9,22.5,22.7,22.3,21.8,21.2,20.9,20.1] C = np.array(values) print(values) print(C) #输出形式跟列表类似,但不相同 print(type(values)) print(type(C))输出结果:
[20.1, 20.8, 21.9, 22.5, 22.7, 22.3, 21.8, 21.2, 20.9, 20.1] [20.1 20.8 21.9 22.5 22.7 22.3 21.8 21.2 20.9 20.1] <class 'list'> <class 'numpy.ndarray'>49、对数据进行批量操作,通常称为矢量化 数组与标量的算术运算将标量值传播到数组的各个元素 大小相等的数组之间的任何算术运算都是元素级,即对应位置元素进行运算
import numpy as np values = [20.1,20.8,21.9,22.5,22.7,22.3,21.8,21.2,20.9,20.1] C = np.array(values) print(C) print(C*9/5+32) #对整体进行操作,结果作用在每一个元素上输出结果:
[20.1 20.8 21.9 22.5 22.7 22.3 21.8 21.2 20.9 20.1] [68.18 69.44 71.42 72.5 72.86 72.14 71.24 70.16 69.62 68.18]50、对应元素进行运算
v = np.array([1,2,3,4,9]) w = np.array([5,6,7,8,9]) print(f'v*5的结果是:{v*5}') print(f'w*5的结果是:{w*5}') print(f'v+w的结果是:{v+w}') print(f'v*w的结果是:{v*w}') print(f'v和w对应元素相等情况:{v==w}')输出结果:
v*5的结果是:[ 5 10 15 20 45] w*5的结果是:[25 30 35 40 45] v+w的结果是:[ 6 8 10 12 18] v*w的结果是:[ 5 12 21 32 81] v和w对应元素相等情况:[False False False False True]51、numpy可以和可视化进行结合,使数据可视化
%matplotlib inline import matplotlib.pyplot as plt Numbers = np.array([20.1,20.8,21.9,22.5,22.7,22.3,21.8,21.2,20.9,20.1]) plt.plot(Numbers) #返回的只是一个对象,如果要出现图,得添加%matplotlib inline plt.show()52、ndarray和list的异同比较 Numpy.ndarray的主要优势在于较小的内存消耗和较好的运行效率(计算效率)
from sys import getsizeof print(f'含三个元素的ndarray占的空间是:{getsizeof(np.array([24,12,57]))}') #数据的空间是96+4*n print(f'不含元素的ndarray占的空间是:{getsizeof(np.array([]))}') print("所以ndarray占的空间是96+4*n") print('-'*75) #list存储每个对象的引用,每个引用占据8个字节 print(f'空列表占的空间是:{getsizeof([])}') print(f'含三个元素的列表占的空间是:{getsizeof([24,12,57])}') print(f'一个整型数据占的空间是:{getsizeof(24)}') print("所以普通列表占的空间是64+8*n+28*n,8是对象的引用占的空间,28是对象实体占的空间") print('-'*75)输出结果:
含三个元素的ndarray占的空间是:108 不含元素的ndarray占的空间是:96 所以ndarray占的空间是96+4*n --------------------------------------------------------------------------- 空列表占的空间是:64 含三个元素的列表占的空间是:88 一个整型数据占的空间是:28 所以普通列表占的空间是64+8*n+28*n,8是对象的引用占的空间,28是对象实体占的空间 ---------------------------------------------------------------------------内存方面:
from sys import getsizeof print(f'含三个元素的ndarray占的空间是:{getsizeof(np.array([24,12,57]))}') #数据的空间是96+4*n print(f'不含元素的ndarray占的空间是:{getsizeof(np.array([]))}') print("所以ndarray占的空间是96+4*n") print('-'*75) #list存储每个对象的引用,每个引用占据8个字节 print(f'空列表占的空间是:{getsizeof([])}') print(f'含三个元素的列表占的空间是:{getsizeof([24,12,57])}') print(f'一个整型数据占的空间是:{getsizeof(24)}') print("所以普通列表占的空间是64+8*n+28*n,8是对象的引用占的空间,28是对象实体占的空间") print('-'*75)时间方面: Timer对象测量执行时间,Timer的构造函数以一个要被测量的语句作为参数,另外一条语句用来 辅助构造执行环境,称为setup语句,Timer对象有一个timeit方法,它的参数number表示被执行次数,单位是秒
import numpy as np size_of_vec = 1000 X_list = range(size_of_vec) Y_list = range(size_of_vec) X = np.arange(size_of_vec) #arange函数跟列表的range类似,但构造出来的是numpy的ndarray Y = np.arange(size_of_vec) def pure_python_version(): Z = [] for i in range(len(X_list)): Z.append(X_list[i]+Y_list[i]) def generator_version(): Z = [X_list[i]+Y_list[i] for i in range(len(X_list))] def numpy_version(): Z = X+Y from timeit import Timer #timer_obj = Timer("x=x+1","x=0") timer_obj1 = Timer("pure_python_version()","from __main__ import pure_python_version") timer_obj2 = Timer("generator_version()","from __main__ import generator_version") timer_obj3 = Timer("numpy_version()","from __main__ import numpy_version") #repeat()函数可以非常方便的调用timeit函数多次并把结果作为一个列表返回 print(f'普通循环用的时间是:{timer_obj1.timeit(10)}') print(f'列表推导式用的时间是:{timer_obj2.timeit(10)}') print(f'numpy中运算用的时间是:{timer_obj3.timeit(10)}') print('-'*35) print("每个函数运行三次之后的结果如下:") print(f'普通循环用的时间是:{timer_obj1.repeat(repeat = 3,number = 10)}') print(f'列表推导式用的时间是:{timer_obj2.repeat(repeat = 3,number = 10)}') print(f'numpy中运算用的时间是:{timer_obj3.repeat(repeat = 3,number = 10)}') print('-'*35) print("在jupyter中,可以用魔法命令简化上述操作,结果如下:") %timeit pure_python_version() %timeit generator_version() %timeit numpy_version()输出结果是:
普通循环用的时间是:0.006618200000957586 列表推导式用的时间是:0.0031413000033353455 numpy中运算用的时间是:0.0008617000057711266 ----------------------------------- 每个函数运行三次之后的结果如下: 普通循环用的时间是:[0.004392900002130773, 0.003513899995596148, 0.003801699996984098] 列表推导式用的时间是:[0.0038260000001173466, 0.00411329999769805, 0.004925399996864144] numpy中运算用的时间是:[3.51999988197349e-05, 0.00019630000315373763, 1.720000000204891e-05] ----------------------------------- 在jupyter中,可以用魔法命令简化上述操作,结果如下: 414 µs ± 19.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 365 µs ± 16.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 2.01 µs ± 882 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)time将会给出当前行的代码运行一次所花费的时间 %time np.random.normal(size = 1000)
%%time将会给出一个cell的代码运行一次所花费的时间 %%time import time for _ in range(1000): #这里”_“表示一个匿名变量,仅使用一次,后续不再使用 time.sleep(0.01) #Wall time : 10.9s
53、创建、索引和切片 1、创建:除了前文提到的从list创建ndarray之外,还可以用arange和linspace arange([start,] stop[, step],[, dtype=None])构造指定步长的整型数组,不过arange创建出来的是一个ndarray而不是列表;dtype是指定数据类型,所以 numpy的ndarray中的数据,类型必须保持一致。 linspace(start,stop,num = 50,endpoint = True,retstep = False)构造等间距的浮点型数组,start和stop是始末数据,num是这段里有多少个数据, endpoint的值为True时,stop值包含在内,为False时stop数值不包含在内;retstep
import numpy as np a = np.arange(1,10) print(a) x = np.arange(0.5,10.4,0.8) #0.8是步长 print(x) print(np.linspace(1,10,7)) #从1到10共7个元素 print(np.linspace(1,10,7,endpoint = False)) #从1到10共7个元素,endpoint=False表示不包含10 samples,spacing = np.linspace(1,10,retstep = True) #retstep = True返回间距 print(spacing) print('-'*40) #print(samples) #创建二维或多维数组 A = np.array([[3.4,8.7,9.9],[1.1,7.8,0.7],[4.1,12.3,4.8]]) print(A) print(A.ndim) #ndim是表示数组是几维的 B = np.array([[[11,12,],[23,56]], [[89,58],[87,16]], [[49,68],[29,34]]]) print(B) print(B.ndim)输出结果:
[1 2 3 4 5 6 7 8 9] [ 0.5 1.3 2.1 2.9 3.7 4.5 5.3 6.1 6.9 7.7 8.5 9.3 10.1] [ 1. 2.5 4. 5.5 7. 8.5 10. ] [1. 2.28571429 3.57142857 4.85714286 6.14285714 7.42857143 8.71428571] 0.1836734693877551 ---------------------------------------- [[ 3.4 8.7 9.9] [ 1.1 7.8 0.7] [ 4.1 12.3 4.8]] 2 [[[11 12] [23 56]] [[89 58] [87 16]] [[49 68] [29 34]]] 354、维度和维度变换 Numpy.shape()或ndarray的shape属性是一个整形元组 shape为(6,3)表示有6行3列,是个二维数组,
import numpy as np x = np.array([[67,63,87], [25,69,87], [85,64,96], [58,95,32], [96,58,12], [87,54,21]]) print(np.shape(x)) print(x.shape)输出: (6, 3) (6, 3)
每个维度也可以称之为一个坐标轴(axis), 沿着行方向从上向下为axis=0,沿着列方向从左到右axis=1,与平面垂直向里axis=2
shape属性也可以用来改变ndarray的shape 上边已经导入了numpy,这里就不再导入了 shape是从根本上改变了数组,reshape只是暂时改变了数组,对原数据并没有发生复制,仅仅是从另一个角度看待这个数据,共享内存
x = np.array([[67,63,87], [25,69,87], [85,64,96], [58,95,32], [96,58,12], [87,54,21]]) print("原数组是:\n",x) x.shape = (3,6) #把原数组改为3行6列 print("改为3行6列后的数组是:\n",x) print('-'*20) x.shape = (2,9) print("改成2行9列后的数组是:\n",x) print('-'*20) y = x.reshape(6,3) print("reshape之前的数组:\n",x) print("y = x.reshape(6,3)中的y:\n",y) print("reshape之后的数组: \n",x) print("判断x和y是否共享内存:",np.may_share_memory(x,y)) x[0,0] = 100 print(y[0,0]) print("由此可见,shape是从根本上改变了数组,reshape只是暂时改变了数组") #把y称为一个视图,对原数据并没有发生复制,仅仅是从另一个角度看待这个数据,共享内存 #reshape的参数order指的是存储顺序,C表示行优先,F表示列优先 arr = np.array([0,1,2,3,4,5,6,7,8,9,10,11]) Cnewarr = arr.reshape((4,3),order = 'C') print("reshape中参数order为C时的新数组:\n",Cnewarr) Fnewarr = arr.reshape((4,3),order = 'F') print("reshape中参数order为F时的新数组:\n",Fnewarr)输出结果:
原数组是: [[67 63 87] [25 69 87] [85 64 96] [58 95 32] [96 58 12] [87 54 21]] 改为3行6列后的数组是: [[67 63 87 25 69 87] [85 64 96 58 95 32] [96 58 12 87 54 21]] -------------------- 改成2行9列后的数组是: [[67 63 87 25 69 87 85 64 96] [58 95 32 96 58 12 87 54 21]] -------------------- reshape之前的数组: [[67 63 87 25 69 87 85 64 96] [58 95 32 96 58 12 87 54 21]] y = x.reshape(6,3)中的y: [[67 63 87] [25 69 87] [85 64 96] [58 95 32] [96 58 12] [87 54 21]] reshape之后的数组: [[67 63 87 25 69 87 85 64 96] [58 95 32 96 58 12 87 54 21]] 判断x和y是否共享内存: True 100 由此可见,shape是从根本上改变了数组,reshape只是暂时改变了数组 reshape中参数order为C时的新数组: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] reshape中参数order为F时的新数组: [[ 0 4 8] [ 1 5 9] [ 2 6 10] [ 3 7 11]]Numpy中提供了flatten()和Ravel()两个函数将多维数组进行一维化,前者产生一个原数据的副本,而后者是原数据的视图
A = np.array([ [ [0,1],[2,3],[4,5],[6,7] ], [ [8,9],[10,11],[12,13],[14,15] ], [ [16,17],[18,19],[20,21],[22,23] ] ]) Flattened = A.flatten() print("使用flatten()得到的数组:\n",Flattened) print("验证flatten()得到的数组与原数组是否共用同一内存:",np.may_share_memory(A,Flattened)) Ravel = A.ravel() print("使用ravel()得到的数组:\n",Ravel) print("验证ravel()得到的数组与原数组是否共用同一内存:",np.may_share_memory(A,Ravel)) print("因此flatte得到的是一个副本,ravel得到的只是一个视图") #ravel和flatten中也有order参数输出结果:
使用flatten()得到的数组: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 验证flatten()得到的数组与原数组是否共用同一内存: False 使用ravel()得到的数组: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 验证ravel()得到的数组与原数组是否共用同一内存: True55、ndarray的索引和切片的方法和list完全相同
A = np.array([ [11,12,13,14,15], [21,22,23,24,25], [31,32,33,34,35], [41,42,43,44,45], [51,52,53,54,55] ]) print("前3行后3列:\n",A[:3,2:]) print("后2行:\n",A[3:,:]) print("最后一列也就是第五列:\n",A[:,4:])输出结果:
前3行后3列: [[13 14 15] [23 24 25] [33 34 35]] 后2行: [[41 42 43 44 45] [51 52 53 54 55]] 最后一列也就是第五列: [[15] [25] [35] [45] [55]]还可以利用步长进行间隔切片 当为list或tuple(元组)创建切片时,是产生一个副本 ndarray的切片产生的是原始数据的视图
X = np.arange(28).reshape(4,7) print("行以2为步长,列以3为步长得到的数组:\n",X[::2,::3]) print("行以1为步长,列以3为步长得到的数组:\n",X[::,::3]) A = np.array([0,1,2,3,4,5,6,7,8,9]) S = A[2:6] S[0] = 22 S[1] = 26 print(A) print("ndarray产生的切片只是原数据的视图,与原数据共享同一内存:",np.may_share_memory(A,S))输出结果:
行以2为步长,列以3为步长得到的数组: [[ 0 3 6] [14 17 20]] 行以1为步长,列以3为步长得到的数组: [[ 0 3 6] [ 7 10 13] [14 17 20] [21 24 27]] [ 0 1 22 26 4 5 6 7 8 9] ndarray产生的切片只是原数据的视图,与原数据共享同一内存: True56、创建特殊的ndarray 创建全1或全0的ndarray,ones()函数的参数t是一个元组,表示ndarray的shape 默认的1是浮点型数据,可以通过dtype参数将其设置为整型。
#创建全1的ndarray import numpy as np E = np.ones((2,3)) print("默认的ones产生的ndarray中的数据是浮点型的:\n",E) F = np.ones((2,3),dtype = int) print("调整dtype后的ndarray中的数据是整型的:\n",F) print('-'*50) #zeros()函数除了将数据填充为0,其他方面与ones()完全相同 Z = np.zeros((2,3)) print("默认的zeros产生的ndarray中的数据是浮点型的:\n",Z) Y = np.zeros((2,3),dtype = int) print("调整dtype后的ndarray中的数据是整型的:\n",Y) print('-'*50) #ones_like()和zeros_liske()创建与已有ndarray相同维数的全1或全0的ndarray A = np.array([1,2,3,4,5]) B = np.ones_like(A) print("构造维数与给定数组一致的全1的数组:\n",B) C = np.zeros_like(A) print("构造维数与给定数组一致的全0的数组:\n",C) print('-'*50) #empty()函数可以创建指定shape和type的空ndarray,这个函数的返回值不会初始化元素的值,有时会看到所有元素都是0,但其实这些值是任意的 D = np.empty((2,4)) print("empty()函数创建的空ndarray:\n",D)输出结果:
默认的ones产生的ndarray中的数据是浮点型的: [[1. 1. 1.] [1. 1. 1.]] 调整dtype后的ndarray中的数据是整型的: [[1 1 1] [1 1 1]] -------------------------------------------------- 默认的zeros产生的ndarray中的数据是浮点型的: [[0. 0. 0.] [0. 0. 0.]] 调整dtype后的ndarray中的数据是整型的: [[0 0 0] [0 0 0]] -------------------------------------------------- 构造维数与给定数组一致的全1的数组: [1 1 1 1 1] 构造维数与给定数组一致的全0的数组: [0 0 0 0 0] -------------------------------------------------- empty()函数创建的空ndarray: [[0.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000] [0.00000000e+000 4.07110092e-321 1.69119330e-306 1.78019625e-306]]57、Identity ndarray:在线性代数中,size为n的Identity矩阵(单位矩阵)指对角线上为1,其他位置为0的方阵 可以通过identity()函数创建单位矩阵;通过eye()创建长方形矩阵,用参数K指定某一条斜线 可以调用ndarray.copy(order = ‘C’)实现array的复制 C表示行优先,F表示列优先,copy()函数是得到了一个新的副本
#通过identity()函数创建单位矩阵 import numpy as np A = np.identity(4) B = np.identity(4,dtype = int) print("用identity()创建的单位方阵:\n",A) print("指定dtype为int之后形成的单位方阵:\n",B) print('-'*50) #通过eye()创建长方形矩阵,用参数K指定某一条斜线 C1 = np.eye(5,8,k = 0,dtype = int) print("用eye()创建的长方形矩阵,其中k=0:\n",C1) print('-'*25) C2 = np.eye(5,8,k = 1,dtype = int) print("用eye()创建的长方形矩阵,其中k=1:\n",C2) print('-'*25) C3 = np.eye(5,8,k = 2,dtype = int) print("用eye()创建的长方形矩阵,其中k=2:\n",C3) print('-'*25) C4 = np.eye(5,8,k = -1,dtype = int) print("用eye()创建的长方形矩阵,其中k=-1:\n",C4) print('-'*50)输出结果:
用identity()创建的单位方阵: [[1. 0. 0. 0.] [0. 1. 0. 0.] [0. 0. 1. 0.] [0. 0. 0. 1.]] 指定dtype为int之后形成的单位方阵: [[1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]] -------------------------------------------------- 用eye()创建的长方形矩阵,其中k=0: [[1 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0]] ------------------------- 用eye()创建的长方形矩阵,其中k=1: [[0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0]] ------------------------- 用eye()创建的长方形矩阵,其中k=2: [[0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0]] ------------------------- 用eye()创建的长方形矩阵,其中k=-1: [[0 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0]] --------------------------------------------------可以调用ndarray.copy(order = ‘C’)实现array的复制 C表示行优先,F表示列优先
#可以调用ndarray.copy(order = 'C')实现array的复制 C表示行优先,F表示列优先 D = np.array([[42,22,12],[44,53,66],],order='F') E = D.copy() print("复制完还未修改的原数组:\n",D) print("经复制得到的数组:\n",E) D[0,0] = 1001 print("复制完修改之后的原数组:\n",D) print("复制得到的数组在原数组被修改之后的情况:\n",E) print("原数组的内存地址:",id(D)) print("复制得到的数组的内存地址:",id(E)) print("判断原数组与复制得到的数组是否共用一个内存:",np.may_share_memory(D,E)) print("由此可得,copy()函数是得到了一个新的副本,而不是原数组的视图")输出结果:
复制完还未修改的原数组: [[42 22 12] [44 53 66]] 经复制得到的数组: [[42 22 12] [44 53 66]] 复制完修改之后的原数组: [[1001 22 12] [ 44 53 66]] 复制得到的数组在原数组被修改之后的情况: [[42 22 12] [44 53 66]] 原数组的内存地址: 2146529076048 复制得到的数组的内存地址: 2146529290960 判断原数组与复制得到的数组是否共用一个内存: False 由此可得,copy()函数是得到了一个新的副本,而不是原数组的视图58、通用函数ufunc(Universal function)包含很多数学函数、统计函数 对ndarray的数据执行元素级别的运算,这些函数接受一个或多个标量值,并产生一个或多个标量值
import numpy as np weight = np.array([50.7,52.5,50,58,55.63,73.25,49.5,45]) print("Minimum ans maximum weight of the students:",np.amin(weight),np.amax(weight)) print("Range of the weight of the student:",np.ptp(weight)) print("Weight below which 70 % student fall:",np.percentile(weight,70))输出结果:
Minimum ans maximum weight of the students: 45.0 73.25 Range of the weight of the student: 28.25 Weight below which 70 % student fall: 55.31759、矩阵操作 一维数组的点积相当于内积,对应元素相乘然后求和 二维数组相乘时,要求A矩阵的列和B矩阵的行相同, 对于N维数组,点积是第一个矩阵A最后一个维度和第二个矩阵B倒数第二个维度对应元素乘积的累加和,即A.shape[-1] == B.shape[-2]
#对于二维数组,乘积是对应元素相乘的结果,但是点积相当于矩阵的乘法 A = np.array([[1,2,3], [4,5,6], [7,8,9]]) B = np.array([[9,8,7], [6,5,4], [3,2,1]]) C = A*B D = A.dot(B) print("A*B的结果是:\n",C) print("A和B点积的结果:\n",D) #ndarray对象和mat对象不同,mat对象是矩阵,*乘就是点积 #ndarray对象做*乘时时对应元素相乘,而mat对象是做的点积 MA = np.mat(A) MB = np.mat(B) R = MA*MB print("mat对象*乘的结果:\n",R) print("ndarray对象做*乘时时对应元素相乘,而mat对象是做的点积") #矩阵相乘是对应行与对应列相乘输出结果:
A*B的结果是: [[ 9 16 21] [24 25 24] [21 16 9]] A和B点积的结果: [[ 30 24 18] [ 84 69 54] [138 114 90]] mat对象*乘的结果: [[ 30 24 18] [ 84 69 54] [138 114 90]] ndarray对象做*乘时时对应元素相乘,而mat对象是做的点积60、广播: 当大ndarray和小ndarray做运算是,让小ndarray在大ndarray层次上不断重复 其实向量和标量运算就体现了广播机制 后缘维度:比如说(3,3)和(3,)、(3,4,2)和(4,2)就是后缘维度相同 广播兼容:要求两个数组的轴长度相等(一个维度就是一个轴),或者其中的一方长度为1
广播兼容的条件:后缘维度相同
#广播兼容的条件:后缘维度相同 A = np.array([[11,12,13],[21,22,23],[31,32,33]]) B = np.array([1,2,3]) #元组只有一个元素时,要在该元素后边加上','' print("A的维度:",A.shape) #A和B的最后一个维度相同即后缘维度相同 print("B的维度:",B.shape) print("A+B的结果:\n",A+B) print("A*B的结果:\n",A*B) print('-'*50)输出结果:
A的维度: (3, 3) B的维度: (3,) A+B的结果: [[12 14 16] [22 24 26] [32 34 36]] A*B的结果: [[11 24 39] [21 44 69] [31 64 99]]广播兼容的条件:一方的轴长度为1
C = np.array([1,2,3]) D = C[:,np.newaxis] #在C的基础上增加一个维度 E = np.array([[11,12,13],[21,22,23],[31,32,33]]) print("原来的C:\n",C) print("增加一个维度之后的C:\n",D) print("3*3的ndarray和3*1的ndarray进行*运算:\n",D*E)输出结果:
原来的C: [1 2 3] 增加一个维度之后的C: [[1] [2] [3]] 3*3的ndarray和3*1的ndarray进行*运算: [[11 12 13] [42 44 46] [93 96 99]]两个维度上的广播
F = np.array([10,20,30]) G = np.array([1,2,3]) H = F[:,np.newaxis] print("G如下:\n",G) print("G的维度是:",G.shape) print("H如下:\n",H) print("H的维度是",H.shape) print("H*G的结果如下:\n",H*G) print("G*H的结果如下:\n",G*H)输出结果:
G如下: [1 2 3] G的维度是: (3,) H如下: [[10] [20] [30]] H的维度是 (3, 1) H*G的结果如下: [[10 20 30] [20 40 60] [30 60 90]] G*H的结果如下: [[10 20 30] [20 40 60] [30 60 90]]如果两个矩阵维度不同,维度小的矩阵前补1,让二者相同 在对应轴长度上,如果二者不同,一方为1,则沿该轴广播 在对应轴长度上,如果二者不同,都不为1,则不能广播
计算距离矩阵:对应元素相减取绝对值
dist = np.array([0,1498,1063,1968,1498]) print(np.abs(dist - dist[:,np.newaxis]))输出结果:
[[ 0 1498 1063 1968 1498] [1498 0 435 470 0] [1063 435 0 905 435] [1968 470 905 0 470] [1498 0 435 470 0]]61、数据连接:将多个数组连接在一起
一维数组的连接
import numpy as np A = np.array([11,22]) B = np.array([18,7,6]) C = np.array([1,3,5]) D = np.concatenate((A,B,C)) #此处(A,B,C)是一个元组, print("一维数组连接起来的结果:\n",D)输出结果:
一维数组连接起来的结果: [11 22 18 7 6 1 3 5]当需要连接多维数组时,被连接的数组必须具有相同的shape,要为concatenate()函数指定axis参数,axis默认为0
data1 = [ [ [11,12,13],[14,15,16],[17,18,19] ], [ [21,22,23],[24,25,26],[27,28,29] ] ] data2 = [ [ [41,42,43],[44,45,46],[47,48,49] ], [ [51,52,53],[54,55,56],[57,58,59] ] ] E = np.array(data1) F = np.array(data2) G1 = np.concatenate((E,F)) #默认的相当于axis=0 print("默认axis=0时连接的结果:\n",G1) G2 =np.concatenate((E,F),axis=1) print("axis = 1 时连接的结果:\n",G2) G3 =np.concatenate((E,F),axis=2) print("axis = 2 时连接的结果:\n",G3)输出结果:
默认axis=0时连接的结果: [[[11 12 13] [14 15 16] [17 18 19]] [[21 22 23] [24 25 26] [27 28 29]] [[41 42 43] [44 45 46] [47 48 49]] [[51 52 53] [54 55 56] [57 58 59]]] axis = 1 时连接的结果: [[[11 12 13] [14 15 16] [17 18 19] [41 42 43] [44 45 46] [47 48 49]] [[21 22 23] [24 25 26] [27 28 29] [51 52 53] [54 55 56] [57 58 59]]] axis = 2 时连接的结果: [[[11 12 13 41 42 43] [14 15 16 44 45 46] [17 18 19 47 48 49]] [[21 22 23 51 52 53] [24 25 26 54 55 56] [27 28 29 57 58 59]]]重复模式:np.tile(给定的ndarray数组,表示重复的次数) 重复的次数是元组形式,可以在多个维度上重复
H = np.array([3.4]) I = np.tile(H,(5,)) print("原来的H如下:\n",H) print("H = np.array([3.4])经np.tile(H,(5,))之后的结果:\n",I) print('-'*25) J = np.array([[1,2],[3,4]]) K = np.tile(J,(3,4)) print("原来的J如下:\n",J) print("J = np.array([[1,2],[3,4]])经np.tile(J,(3,4))之后的结果:\n",K) #行方向重复三次,列方向重复四次输出结果:
原来的H如下: [3.4] H = np.array([3.4])经np.tile(H,(5,))之后的结果: [3.4 3.4 3.4 3.4 3.4] ------------------------- 原来的J如下: [[1 2] [3 4]] J = np.array([[1,2],[3,4]])经np.tile(J,(3,4))之后的结果: [[1 2 1 2 1 2 1 2] [3 4 3 4 3 4 3 4] [1 2 1 2 1 2 1 2] [3 4 3 4 3 4 3 4] [1 2 1 2 1 2 1 2] [3 4 3 4 3 4 3 4]]