中的np.ascontiguousarray()函数在Numpy文档中解释道:“返回内存中的连续数组(ndim>=1)(C顺序)。”ascontiguousarray函数将内存不连续存储的数组转换为内存中连续存储的数组,使操作速度更快。C序vsFortran序C序是指行优先序(Row-majorOrder),即内存中同一行的元素一起存在,而FortranOrder是指列优先序(Column-majorOrder),即内存中同一列的元素是一起存在的。Pascal、C、C++和Python都是行优先存储,而Fortran和MatLab是列优先存储。连续数组连续数组是指数组存放在内存中的地址也是连续的(注意内存地址实际上是一维的)。二维数组arr=np.arange(12).reshape(3,4)。数组结构在内存中其实是这样存储的:arr是C序的,内存是row-first的。如果你想向下移动一列,你需要跳过3个块(例如,从0到4你只需要跳过1、2和3)。如果转置,arr.T不具备C的连续性特征,因为元素在内存中的地址不变,同一行的相邻元素在内存中不连续:此时arr.T变成了Fortran顺序,因为相邻列中的元素相邻存储在内存中。从性能上来说,在内存中获取相邻地址比不相邻地址要快很多(从RAM中读取一个值时,可以将一块地址中的值一起读取并存入Cache中),这样意味着对连续数组的操作要快得多。由于arr是C连续的,因此对它的行操作比列操作更快。一般来说np.sum(arr,axis=1)#按行求和会比np.sum(arr,axis=0)#按列求和稍微快一些。同样,在arr.T上,列操作比行操作快。在Numpy中使用np.ascontiguousarray(),随机初始化的数组默认是C连续的。经过不规则的切片操作后,连续性会发生变化,可能变得既不是C连续的,也不是Fortran连续的。你可以通过数组的.flags属性来判断一个数组是C连续还是Fortran连续>>>importnumpyasnp>>>arr=np.arange(12).reshape(3,4)>>>arr。flagsC_CONTIGUOUS:TrueF_CONTIGUOUS:FalseOWNDATA:FalseWRITEABLE:TrueALIGNED:TrueWRITEBACKIFCOPY:FalseUPDATEIFCOPY:False从输出中,我们可以看到数组arr是C连续的。对arr逐列切片操作,每行的值不变,所以还是C连续的:>>>arrarray([[0,1,2,3],[4,5,6,7],[8,9,10,11]])>>>arr1=arr[:2,:]>>>arr1array([[0,1,2,3],[4,5,6,7]])>>>arr1.flagsC_CONTIGUOUS:真F_CONTIGUOUS:假OWNDATA:假WRITEABLE:真对齐:真WRITEBACKIFCOPY:假UPDATEIFCOPY:假>>arr1=arr[:,1:3]>>>arr1.flagsC_CONTIGUOUS:FalseF_CONTIGUOUS:FalseOWNDATA:FalseWRITEABLE:TrueALIGNED:TrueWRITEBACKIFCOPY:FalseUPDATEIFCOPY:False此时可以使用ascontiguousarray函数来设置它成为连续的:>>>arr2=np.ascontiguousarray(arr1)>>>arr2.flagsC_CONTIGUOUS:TrueF_CONTIGUOUS:FalseOWNDATA:TrueWRITEABLE:TrueALIGNED:TrueWRITEBACKIFCOPY:FalseUPDATEIFCOPY:FalseReferencesaysfromascontiguousarrayinNumpy开始-了解Numpy文档ArtiPub自动出版
