NumPy 數(shù)組副本和視圖

副本是一個數(shù)據(jù)的完整的拷貝,如果我們對副本進(jìn)行修改,它不會影響到原始數(shù)據(jù),物理內(nèi)存不在同一位置。
視圖是數(shù)據(jù)的一個別稱或引用,通過該別稱或引用亦便可訪問、操作原有數(shù)據(jù),但原有數(shù)據(jù)不會產(chǎn)生拷貝。如果我們對視圖進(jìn)行修改,它會影響到原始數(shù)據(jù),物理內(nèi)存在同一位置。

副本和視圖之間的區(qū)別

副本和數(shù)組視圖之間的主要區(qū)別在于副本是一個新數(shù)組,而這個視圖只是原始數(shù)組的視圖。副本擁有數(shù)據(jù),對副本所做的任何更改都不會影響原始數(shù)組,對原始數(shù)組所做的任何更改也不會影響副本。視圖不擁有數(shù)據(jù),對視圖所做的任何更改都會影響原始數(shù)組,而對原始數(shù)組所做的任何更改都會影響視圖。

視圖一般發(fā)生在:

1、numpy 的切片操作返回原數(shù)據(jù)的視圖。2、調(diào)用 ndarray 的 view() 函數(shù)產(chǎn)生一個視圖。

副本一般發(fā)生在:

Python 序列的切片操作,調(diào)用deepCopy()函數(shù)。調(diào)用 ndarray 的 copy() 函數(shù)產(chǎn)生一個副本。

無復(fù)制

簡單的賦值不會創(chuàng)建數(shù)組對象的副本。 相反,它使用原始數(shù)組的相同id()來訪問它。 id()返回 Python 對象的通用標(biāo)識符,類似于 C 中的指針。此外,一個數(shù)組的任何變化都反映在另一個數(shù)組上。 例如,一個數(shù)組的形狀改變也會改變另一個數(shù)組的形狀。

>>> import numpy as np
>>> a = np.arange(6)
>>> print ('我們的數(shù)組是:',a)
我們的數(shù)組是: [0 1 2 3 4 5]
>>> print ('調(diào)用 id() 函數(shù):',id(a))
調(diào)用 id() 函數(shù): 4553321728
>>> b = a
>>> print (b)
[0 1 2 3 4 5]
>>> print ('b 擁有相同 id():',id(b))
b 擁有相同 id(): 4553321728
>>> b.shape = 3,2
>>> print (b)
[[0 1]
 [2 3]
 [4 5]]
>>> print (a)
[[0 1]
 [2 3]
 [4 5]]
>>>

視圖或淺拷貝

ndarray.view() 方會創(chuàng)建一個新的數(shù)組對象,該方法創(chuàng)建的新數(shù)組的維數(shù)更改不會更改原始數(shù)據(jù)的維數(shù)。

import numpy as np 
 
 # 最開始 a 是個 3X2 的數(shù)組
a = np.arange(6).reshape(3,2) 
print ('數(shù)組 a:')
print (a)
print ('創(chuàng)建 a 的視圖:')
b = a.view() 
print (b)
print ('兩個數(shù)組的 id() 不同:')
print ('a 的 id():')
print (id(a))
print ('b 的 id():' )
print (id(b))
 # 修改 b 的形狀,并不會修改 a
b.shape = 2,3
print ('b 的形狀:')
print (b)
print ('a 的形狀:')
print (a)

輸出結(jié)果為:

數(shù)組 a:
[[0 1]
 [2 3]
 [4 5]]
創(chuàng)建 a 的視圖:
[[0 1]
 [2 3]
 [4 5]]
兩個數(shù)組的 id() 不同:
a 的 id():
4314786992
b 的 id():
4315171296
b 的形狀:
[[0 1 2]
 [3 4 5]]
a 的形狀:
[[0 1]
 [2 3]
 [4 5]]

使用切片創(chuàng)建視圖修改數(shù)據(jù)會影響到原始數(shù)組:

import numpy as np 
arr = np.arange(12)
print ('我們的數(shù)組:')
print (arr)
print ('創(chuàng)建切片:')
a=arr[2:]
b=arr[2:]
a[1]=123456
b[2]=23445
print(arr)
print(id(a),id(b),id(arr[3:]))

輸出結(jié)果為:

我們的數(shù)組:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
創(chuàng)建切片:
[ 0 1 2 123456 23445 5 6 7 8 9
     10 11]
4669930672 4444330304 4670012352
Process finished with exit code 0

變量 a,b 都是 arr 的一部分視圖,對視圖的修改會直接反映到原數(shù)據(jù)中。但是我們觀察 a,b 的 id,他們是不同的,也就是說,視圖雖然指向原數(shù)據(jù),但是他們和賦值引用還是有區(qū)別的。

副本或深拷貝

ndarray.copy() 函數(shù)創(chuàng)建一個副本。 對副本數(shù)據(jù)進(jìn)行修改,不會影響到原始數(shù)據(jù),它們物理內(nèi)存不在同一位置。

import numpy as np 
 
a = np.array([[10,10], [2,3], [4,5]]) 
print ('數(shù)組 a:')
print (a)
print ('創(chuàng)建 a 的深層副本:')
b = a.copy() 
print ('數(shù)組 b:')
print (b)
 # b 與 a 不共享任何內(nèi)容 
print ('我們能夠?qū)懭?nbsp;b 來寫入 a 嗎?')
print (b is a)
print ('修改 b 的內(nèi)容:')
b[0,0] = 100 
print ('修改后的數(shù)組 b:')
print (b)
print ('a 保持不變:')
print (a)

輸出結(jié)果為:

數(shù)組 a:
[[10 10]
 [ 2 3]
 [ 4 5]]
創(chuàng)建 a 的深層副本:
數(shù)組 b:
[[10 10]
 [ 2 3]
 [ 4 5]]
我們能夠?qū)懭?nbsp;b 來寫入 a 嗎?
False
修改 b 的內(nèi)容:
修改后的數(shù)組 b:
[[100 10]
 [ 2 3]
 [ 4 5]]
a 保持不變:
[[10 10]
 [ 2 3]
 [ 4 5]]
丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清