天天看點

numpy中視圖和副本的差別

      副本(深拷貝)是一個資料的完整的拷貝,如果我們對其進行修改,它不會影響到原始資料,實體記憶體(id( ))不在同一位置。

實作方式:

  1. Python 序列的切片操作;
  2. Python調用copy.deepCopy()函數(詳見上一篇部落格);
  3. 調用 ndarray 的 copy() 函數産生一個副本(注意:ndarray沒有deepcopy()屬性,同時這裡的copy()是ndarray的自帶屬性,不需要引入copy子產品;)

Example1:

import numpy as np

b = [[4,5],[1,2]]
c = np.array(b)
print('c',c)
d = c.copy()
print(c is d)
c[1][0] = 0
print('After changing:')
print('c',c)
print('d',d)
           
結果:
c [[4 5]
 [1 2]]
False
After changing:
c [[4 5]
 [0 2]]
d [[4 5]
 [1 2]]
           

Example2:注意這種一維的特殊情況,array裡面的list元素發生了改變

import numpy as np

b = [4,5,[1,2]]
c = np.array(b)
print('c',c)
d = c.copy()
print(c is d)
c[2][0] = 0
print('After changing:')
print('c',c)
print('d',d)
           
結果:
c [4 5 list([1, 2])]
False
After changing:
c [4 5 list([0, 2])]
d [4 5 list([0, 2])]
           

      視圖是資料的一個别稱或引用,通過該别稱或引用亦便可通路、操作原有資料,雖然視圖和原始資料的id不同,但是如果我們對視圖進行修改,它會影響到原始資料,實體記憶體在同一位置。

實作方式:

  1. numpy 的切片操作傳回原資料的視圖;
  2. 調用 ndarray 的 view() 函數産生一個視圖;

Example1:對一維的ndarray對象切片:

import numpy as np 
 
arr = np.arange(12)
print ('我們的數組:')
print (arr)
print ('建立切片:')
a=arr[3:]
b=arr[3:]
a[1]=123
b[2]=234
print(arr)
print(id(a),id(b),id(arr[3:]))
           
我們的數組:
[ 0  1  2  3  4  5  6  7  8  9 10 11]
建立切片:
[  0   1   2   3 123 234   6   7   8   9  10  11]
4545878416 4545878496 4545878576
           

Example2:對二維的ndarray對象切片

import numpy as np 
 
# 最開始 a 是個 3X2 的數組
arr = np.arange(6).reshape(3,2)  
print ('數組 arr:')
print (arr)
print ('通過切片建立 arr 的視圖b:')
b = arr[1:,:]  
print (b)
print ('兩個數組的 id() 不同:')
print ('arr 的 id():')
print (id(arr))
print ('b 的 id():' )
print (id(b))
print('改變b的元素值後:')
b[1][0] = 9
print('arr:',arr)
print('b:',b)
           
結果:
數組 arr:
[[0 1]
 [2 3]
 [4 5]]
通過切片建立 arr 的視圖b:
[[2 3]
 [4 5]]
兩個數組的 id() 不同:
arr 的 id():
4587630880
b 的 id():
4587631200
改變b的元素值後:
arr: [[0 1]
 [2 3]
 [9 5]]
b: [[2 3]
 [9 5]]
           

Example3:ndarray.view() 方會建立一個新的對象,對新對象維數更改不會更改原始資料的維數。

import numpy as np 
a = np.arange(6).reshape(3,2) 

print ('Array a:' )
print (a)

print ('Create view of a:') 
b = a.view() 
print (b)  

print ('id() for both the arrays are different:' )
print ('id() of a:')
print (id(a)) 
print ('id() of b:')
print (id(b)) 

print('Change the shape of b. It does not change the shape of a ')
b.shape = 2,3 

print ('Shape of b:') 
print (b)  

print ('Shape of a:')
print (a)
           
結果:
Array a:
[[0 1]
 [2 3]
 [4 5]]
Create view of a:
[[0 1]
 [2 3]
 [4 5]]
id() for both the arrays are different:
id() of a:
4587632800
id() of b:
4586601568
Change the shape of b. It does not change the shape of a 
Shape of b:
[[0 1 2]
 [3 4 5]]
Shape of a:
[[0 1]
 [2 3]
 [4 5]]
           

參考文章:

https://www.runoob.com/numpy/numpy-copies-and-views.html

http://www.cnblogs.com/hellcat/p/8715830.html