【Python】NumPy 中 ravel() 正确打开方式
最近在看书时,对numpy的ravel()的有些疑惑,书上这样写到“如果结果中的值在原始数组中是连续的,则ravel 不会生成底层数值的副本”,度娘后,发现大部分的说法都是得到原数组的视图,但是按照书上的说法,是可以产生副本的,只要结果的值在原始数组中不连续。
刚开始不太理解,这里所谓的连续是指什么?后来发现,这个连续是指的是元素顺序,reval()中有个参数【order】,这个参数指定了重塑顺序。
In [58]: arr2
Out[58]:
array([[ 1, 1, -1],
[ 0, -3, 6]]) # arr2 默认安装C顺序展开
In [59]: arr3 = np.ravel(arr2,order = 'C') # C顺序,即是按行方向顺序
In [60]: arr3
Out[60]: array([ 1, 1, -1, 0, -3, 6]) # arr2,arr3都是按照C顺序展开
In [72]: arr3.base is arr2 # arr3基于arr2
Out[72]: True
In [73]: np.may_share_memory(arr2,arr3) # arr3,arr2共享内存,则arr3为arr2的视图
Out[73]: True
In [62]: arr4 = np.ravel(arr2,order = 'F') #arr4 按照F顺序,即是列顺序重塑
In [63]: arr4
Out[63]: array([ 1, 0, 1, -3, -1, 6]) #可以看出顺序与arr2的不同
In [64]: arr4.base is arr2 #arr4 不是基于arr2
Out[64]: False
In [65]: np.may_share_memory(arr2,arr4) #arr4,arr2 不共享内存
Out[65]: False
In [74]: arr4.flags.owndata #arr4拥有自己的数据,说明独立于arr2,是一个副本
Out[74]: True
In [66]: arr5 = np.ravel(arr2.T, order='A') #A顺序,应该是针对于转置后的重塑
In [67]: arr5
Out[67]: array([ 1, 1, -1, 0, -3, 6]) #得到结果顺序与arr2的一致,也是C顺序
In [68]: np.may_share_memory(arr2,arr5) # arr5,arr2共享内存,则arr5为arr2的视图
Out[68]: True
In [69]: arr6 = np.ravel(arr2.swapaxes(0,1), order='K') #A顺序,应该是针对于轴交换后的重塑
In [70]: arr6
Out[70]: array([ 1, 1, -1, 0, -3, 6]) #得到结果顺序与arr2的一致,也是C顺序
In [71]: np.may_share_memory(arr2,arr6) # arr6,arr2共享内存,则arr6为arr2的视图
Out[71]: True
所以ravel()的结果不一定就是原数组的视图,这个要看具体的情况,不过一般重塑都是使用默认的order参数,按照C顺序重塑,但是使用时也要注意,避免错把视图当做副本,修改视图影响原本的数组。
或者直接使用flatten(),不管参数【order】如何都是,返回一份拷贝,对拷贝所做的修改不会影响(reflects)原始数组,
最后,也可以通过reshape(-1)使原多维数组转化为一维数组,reshape(x, y)使其转化为其他形状,不过注意使用reshape()都是返回原始数组的视图。
总结下,
1,reshape() 返回原始数组的视图;
2,ravel() 返回原始数据的视图或者副本,只有在参数order = ‘F’时返回副本;
3,flatten() 返回原始数组的副本;
以上有错误的,可以评论指出,拍砖!!!