第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Numpy 副本與視圖

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

副本是一個(gè)數(shù)據(jù)的完整的拷貝,如果我們對副本進(jìn)行修改,它不會影響到原始數(shù)據(jù),物理內(nèi)存不在同一位置。

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

  • Numpy 的切片操作返回原數(shù)據(jù)的視圖;
  • 調(diào)用 ndarray 的 view() 函數(shù)產(chǎn)生一個(gè)視圖。

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

  • 在對 Python 序列進(jìn)行切片操作時(shí),同時(shí)調(diào)用 deepcopy() 函數(shù);
  • 調(diào)用 ndarray (或其切片)的時(shí)候,同時(shí)調(diào)用 copy() 函數(shù)產(chǎn)生一個(gè)副本。

1. 直接賦值

1.1 ndarray 的賦值特性

對已經(jīng)產(chǎn)生的 ndarray 對象,將該對象通過 = 方式再次賦值給其他變量,并不會創(chuàng)建數(shù)組對象的副本。即在該過程中產(chǎn)生的變量,都指向同一塊物理內(nèi)存地址。

案例

對于不同的變量,可以用 id() 函數(shù)來查看其對應(yīng)的通用標(biāo)識符,進(jìn)而判斷是否具有同一性。

a = np.arange(12)
print("數(shù)組a:", a)
print("數(shù)組a的id:", id(a))

打印結(jié)果為:

out:
    數(shù)組a: [ 0  1  2  3  4  5  6  7  8  9 10 11]
    數(shù)組a的id1383613133408

通過把 a 賦值給 b,創(chuàng)建一個(gè)新變量:

b = a
print("數(shù)組a:", b)
print("數(shù)組a的id:", id(b))

打印結(jié)果為:

數(shù)組a: [ 0  1  2  3  4  5  6  7  8  9 10 11]
數(shù)組a的id1383613133408

可以發(fā)現(xiàn) a 和 b 的 id 完全一致,并且我們可以利用 is 判定符來佐證同一性的判定結(jié)論:

a is b
out:
    True

案例

在對 a 進(jìn)行修改操作時(shí),響應(yīng)的效果也會同步顯示在 b 變量中。

a.shape=(3,4)
a
out:
    array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

修改 a 為二維數(shù)組,相應(yīng)的,b也會產(chǎn)生同樣的變化:

b
out:
    array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

2 視圖或淺拷貝

2.1 ndarray.view()

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

a = np.arange(6).reshape(3,2)
print("數(shù)組a:", a)
print("數(shù)組a的id:", id(a))

打印結(jié)果為:

數(shù)組a: [[0 1]
        [2 3]
        [4 5]]
數(shù)組a的id1383613212272

創(chuàng)建 a 的視圖 b:

b = a.view()
print("視圖b:", b)
print("視圖b的id:", id(b))

打印結(jié)果為:

視圖b: [[0 1]
 		[2 3]
 		[4 5]]
視圖b的id1383613212672

可以看到,在視圖產(chǎn)生的過程中,a 和 b 的 id 并不一致,這說明視圖和直接賦值是不一樣的。

案例

對視圖 b 進(jìn)行元素修改,該修改會同步反饋在變量 a 中:

b[0,0]=100
print("數(shù)組b:", b)
print("數(shù)組a:", a)

打印結(jié)果為:

數(shù)組b: [[100   1]
 		[  2   3]
 		[  4   5]]
數(shù)組a: [[100   1]
 		[  2   3]
 		[  4   5]]

案例

對視圖 b 進(jìn)行形狀修改,并不影響到 a:

b.shape=2,3
print("數(shù)組b:", b)
print("數(shù)組a:", a)

打印結(jié)果為:

數(shù)組b: array([[100,   1,   2],
            [  3,   4,   5]])
數(shù)組a: [[100   1]
 		[  2   3]
 		[  4   5]]

2.2 切片

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

arr = np.arange(12)
print ("數(shù)組arr:", arr)

創(chuàng)建的 arr 數(shù)組為:

數(shù)組arr: [ 0  1  2  3  4  5  6  7  8  9 10 11]

分別通過切片產(chǎn)生 a 和 b:

a=arr[3:]
b=arr[3:]
print("修改前的切片a:", a)
print("修改前的切片b:", b)

切片結(jié)果 a 和 b 為:

修改前的切片a: [ 3  4  5  6  7  8  9 10 11]
修改前的切片b: [ 3  4  5  6  7  8  9 10 11]

分別改變切片 a 和 b 中的元素:

a[1]=123
b[2]=234
print("修改后的切片a:", a)
print("修改后的切片b:", b)

修改后的 a 和 b 為:

修改后的切片a: [  3 123 234   6   7   8   9  10  11]
修改后的切片b: [  3 123 234   6   7   8   9  10  11]

可以看到,對 a 和 b 所做的修改,都同時(shí)出現(xiàn)了。這說明切片直接是互相影響的。

print("修改后的原數(shù)組arr:", arr)

打印結(jié)果為:

修改后的原數(shù)組arr: [  0   1   2   3 123 234   6   7   8   9  10  11]

綜合看下來,我們可以發(fā)現(xiàn):變量 a,b 都是 arr 的一部分視圖,對視圖的修改會直接反映到原數(shù)據(jù)和相關(guān)切片中。

3 副本或深拷貝

3.1 ndarray.copy()

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

案例

創(chuàng)建數(shù)組 a,并產(chǎn)生 a 的副本,記為 b:

a = np.array([[0,1], [2,3], [4,5]])
b = a.copy()

判斷 a 和 b 是否具有同一性:

b is a
out:
    False

可以看到,a 和 b 互相獨(dú)立,這和賦值顯然不同。

對副本進(jìn)行修改,觀察原始數(shù)組:

b[0,0]=100
print("修改后的數(shù)組b:", b)
print("原始數(shù)組a:", a)

打印結(jié)果為:

修改后的數(shù)組b: [[100   1]
			 [  2   3]
			 [  4   5]]
原始數(shù)組a: [[0 1]
		  [2 3]
		  [4 5]]

可以發(fā)現(xiàn),副本產(chǎn)生的變化,并不會對原始數(shù)組產(chǎn)生影響。

4. 小結(jié)

本小節(jié)講解了視圖和副本的概念和區(qū)別。副本是對原始數(shù)組的完整拷貝,二者互相獨(dú)立,并不互相影響,但是物理內(nèi)存的開銷會加倍。而視圖(切片)是對原始數(shù)據(jù)的一種映射,物理內(nèi)存的開銷相對小一些;對視圖(切片)的元素更改,會相應(yīng)地反映到原始數(shù)組中,這是二者最大的區(qū)別。