NumPy副本和視圖

NumPy - 副本和視圖

在執行函數時,其中一些返回輸入數組的副本,而另一些返回視圖。 當內容物理存儲在另一個位置時,稱為副本。 另一方面,如果提供了相同記憶體內容的不同視圖,我們將其稱為視圖

無複製

簡單的賦值不會創建數組對象的副本。 相反,它使用原始數組的相同id()來訪問它。 id()返回 Python 對象的通用識別字,類似於 C 中的指針。

此外,一個數組的任何變化都反映在另一個數組上。 例如,一個數組的形狀改變也會改變另一個數組的形狀。

示例

import numpy as np
a = np.arange(6)
print  '我們的數組是:'
print a
print  '調用 id() 函數:'
print id(a)
print  'a 賦值給 b:'
b = a
print b
print  'b 擁有相同 id():'
print id(b)
print  '修改 b 的形狀:'
b.shape =  3,2
print b
print  'a 的形狀也修改了:'
print a

輸出如下:

我們的數組是:
[0 1 2 3 4 5]

調用 id() 函數:

139747815479536

a 賦值給 b:

[0 1 2 3 4 5]
b 擁有相同 id():

139747815479536

修改 b 的形狀:

[[0 1]
 [2 3]
 [4 5]]

a 的形狀也修改了:

[[0 1]
 [2 3]
 [4 5]]

視圖或淺複製

NumPy 擁有ndarray.view()方法,它是一個新的數組對象,並可查看原始數組的相同數據。 與前一種情況不同,新數組的維數更改不會更改原始數據的維數。

示例

import numpy as np
# 最開始 a 是個 3X2 的數組

a = np.arange(6).reshape(3,2)
print  '數組 a:'
print a
print  '創建 a 的視圖:'
b = a.view()
print b
print  '兩個數組的 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

輸出如下:

數組 a:

[[0 1]
 [2 3]
 [4 5]]

創建 a 的視圖:
[[0 1]
 [2 3]
 [4 5]]

兩個數組的 id() 不同:

a 的 id():

140424307227264
b 的 id():

140424151696288

b 的形狀:

[[0 1 2]
 [3 4 5]]

a 的形狀:

[[0 1]
 [2 3]
 [4 5]]

數組的切片也會創建視圖:

示例

import numpy as np
a = np.array([[10,10],  [2,3],  [4,5]])
print  '我們的數組:'
print a
print  '創建切片:'
s = a[:,  :2]
print s

輸出如下:

我們的數組:

[[10 10]
 [ 2 3]
 [ 4 5]]

創建切片:

[[10 10]
 [ 2 3]
 [ 4 5]]

深複製

ndarray.copy()函數創建一個深層副本。 它是數組及其數據的完整副本,不與原始數組共用。

示例

import numpy as np
a = np.array([[10,10],  [2,3],  [4,5]])
print  '數組 a:'
print a
print  '創建 a 的深層副本:'
b = a.copy()
print  '數組 b:'
print b
# b 與 a 不共用任何內容

print  '我們能夠寫入 b 來寫入 a 嗎?'
print b is a
print  '修改 b 的內容:'
b[0,0]  =  100
print  '修改後的數組 b:'
print b
print  'a 保持不變:'
print a

輸出如下:

數組 a:

[[10 10]
 [ 2 3]
 [ 4 5]]

創建 a 的深層副本:
數組 b:

[[10 10]
 [ 2 3]
 [ 4 5]]
我們能夠寫入 b 來寫入 a 嗎?
False

修改 b 的內容:
修改後的數組 b:

[[100 10]
 [ 2 3]
 [ 4 5]]

a 保持不變:

[[10 10]
 [ 2 3]
 [ 4 5]]

上一篇: NumPy位元組交換 下一篇: NumPy矩陣庫