【Python】NumPy 中 ravel() 正確打開方式

【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() 返回原始數組的副本;

以上有錯誤的,可以評論指出,拍磚!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章