【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() 返回原始數組的副本;
以上有錯誤的,可以評論指出,拍磚!!!