這篇文章本是我在 segmentfault 上的一個回答,但是越來越覺得有必要單獨拿出來,畢竟這個問題挺常見的。具體可參看 numpy
官方文檔 。
正文
numpy
關於copy
有三種情況,完全不復制、視圖(view
)或者叫淺複製(shallow copy
)和深複製(deep copy
)。
而 b = a[:]
這種形式就屬於第二種,即視圖,這本質上是一種切片操作(slicing
),所有的切片操作返回的都是視圖。具體來說,b = a[:]
會創建一個新的對象 b
(所以 id(b)
和id(a)
返回的結果是不一樣的),但是 b
的數據完全來自於a
,和 a
保持完全一致,換句話說,b
的數據完全由a
保管,他們兩個的數據變化是一致的,可以看下面的示例:
a = np.arange(4) # array([0, 1, 2, 3])
b = a[:] # array([0, 1, 2, 3])
b.flags.owndata # 返回 False,b 並不保管數據
a.flags.owndata # 返回 True,數據由 a 保管
# 改變 a 同時也影響到 b
a[-1] = 10 # array([0, 1, 2, 10])
b # array([0, 1, 2, 10])
# 改變 b 同時也影響到 a
b[0] = 10 # array([10, 1, 2, 10])
a # array([10, 1, 2, 10])
b = a
和 b = a[:]
的差別就在於後者會創建新的對象,前者不會。兩種方式都會導致 a
和 b
的數據相互影響。
要想不讓 a
的改動影響到 b
,可以使用深複製:
unique_b = a.copy()