Python?numpy視圖與副本
前言:
繼上一篇對(duì)numpy 模塊之ndarray一文中對(duì) ndarray 內(nèi)存結(jié)構(gòu)主要分為兩部分:
metdata
:存放數(shù)組類型dtype、數(shù)組維度ndim、維度數(shù)量shape、維間距strides等raw bata
:存放原始數(shù)據(jù)data
在 metdata
中包含著關(guān)于數(shù)組相關(guān)信息,可以幫助我們?cè)跀?shù)組ndarray
中快速索引和解釋指定的數(shù)據(jù)
除此了對(duì)數(shù)組進(jìn)行索引操作外,也會(huì)對(duì)數(shù)組的原數(shù)據(jù)進(jìn)行類似與之前“拷貝”操作。
眾所周知,在 Python 中大家應(yīng)該對(duì)深淺拷貝有一定的印象吧,在 numpy 中則換成了“視圖”與“副本”的概念了。
相信大家和我一樣對(duì)此存在疑問(wèn),十萬(wàn)個(gè)為什么涌上心頭了,“視圖是什么?”,“什么是副本?”
因此,本期我們一起來(lái)學(xué)習(xí) numpy 模塊中比較新奇的概念視圖與副本,Let's go~
1. 簡(jiǎn)單講解
我們之前在學(xué)習(xí) Python 賦值、深淺拷貝時(shí),在代碼添加中對(duì)比兩個(gè)對(duì)象的地址id()是否一致。
同理,按照這樣的思路,numpy 中也可以對(duì)比兩個(gè)數(shù)組地址是否一樣。
同時(shí),在 numpy 數(shù)組對(duì)象ndarray 也提供許多字段,方便讓我們進(jìn)一步地查看數(shù)組內(nèi)部的差異
ndarray.flags : 查看數(shù)組存儲(chǔ)策略、讀寫權(quán)限、對(duì)象等
C_CONTIGUOUS (C)
行優(yōu)先存儲(chǔ)F_CONTIGUOUS
列優(yōu)先存儲(chǔ)OWNDATA
數(shù)據(jù)所有者WRITEABLE
編寫權(quán)限ALIGNED
數(shù)據(jù)元素與硬件指針對(duì)齊WRITEBACKIFCOPY
數(shù)組是其他數(shù)組的副本UPDATEIFCOPY
已棄用
注:flags 相關(guān)屬性名稱可以單獨(dú)調(diào)用例如 flags.writeable
ndarray.base
: 查看數(shù)組中的元素是否來(lái)自其他數(shù)組ndarray.nbytes
: 查看數(shù)組中數(shù)據(jù)占用的字節(jié)數(shù)getsizeof(item)
: 查看數(shù)組占用的內(nèi)存空點(diǎn)
介紹完上述指標(biāo),我們來(lái)小試一下:
>>> import numpy as np >>> a = np.array([1,2,3,4]) >>> print(a[1:3]) [2 3] >>> print(a[[1,2]]) [2 3] >>>
查看a[1:3] 與 a[[1,2]] 內(nèi)存地址,它們倆位置不一樣,a[[1,2]]意味發(fā)生了深拷貝本(副本),a[1:3] 是原數(shù)組a引用(視圖)
>>> print(id(a[1:3])) 2247482965008 >>> print(id(a[[1,2]])) 2247482964928
查看ndarray.owndata
屬性,發(fā)現(xiàn)a[1:3] 數(shù)據(jù)來(lái)自a數(shù)組的,而a[[1,2]]是自身數(shù)據(jù)的
>>> print(a.flags.owndata) True >>> print(a[1:3].flags.owndata) False >>> print(a[[1,2]].flags.owndata) True
我們?cè)诳匆幌?ndarray.base
屬性,果真印證了使用flags.owndata
查詢的結(jié)果,a[1:3] 不是數(shù)據(jù)所有者,而數(shù)據(jù)來(lái)源數(shù)組a;
a[[1,2]] 是數(shù)據(jù)所有者,數(shù)據(jù)來(lái)源本身(None)
>>> print(a[[1,2]].base) None >>> print(a[1:3].base) [1 2 3 4]
2. 視圖
視圖概念
我們通過(guò)上述簡(jiǎn)單例子,可以知道 a[1:3] 不是數(shù)據(jù)所有者,數(shù)據(jù)來(lái)源于對(duì)數(shù)組a的引用(淺拷貝)。
因此,我們應(yīng)該對(duì)視圖有了基本的認(rèn)識(shí)了,看一下官方怎么描述視圖的
No copy at All。 Simple assignments make no copy of objects or their data.
視圖,是對(duì)原數(shù)組進(jìn)行引用拷貝,共享原始數(shù)組的數(shù)據(jù)。
視圖應(yīng)用
視圖在numpy中廣泛使用,視圖一般產(chǎn)生有兩種場(chǎng)景:
- 當(dāng)對(duì)原始數(shù)組進(jìn)行引用時(shí)
- 當(dāng)自身無(wú)數(shù)據(jù),與原數(shù)組共享數(shù)據(jù)時(shí)
>>> import numpy as np >>> a = np.array([1,2,3,4]) >>> b = a >>> b is a True >>> id(a) 2247207679680 >>> id(b) 2247207679680 >>>
我們可以看到 a 與 b 是 同享同一個(gè)數(shù)據(jù)空間的
在numpy
模塊諸如索引、切片、函數(shù)view()
,reshape()
等返回視圖結(jié)果
>>> arr = np.arange(10) >>> arr_view = arr.view() >>> arr.shape = (2,5) >>> arr_reshape = arr.reshape(5,2) # ndarray.base 屬性 >>> print(arr.base) None >>> print(arr_view.base) [[0 1 2 3 4] ?[5 6 7 8 9]] >>> print(arr_reshape.base) [[0 1 2 3 4] ?[5 6 7 8 9]] # ndarray.flags.owndata 屬性 >>> print(arr.flags.owndata) True >>> print(arr_view.flags.owndata) False >>> print(arr_reshape.flags.owndata) False >>>
視圖優(yōu)點(diǎn)
在 numpy 中 視圖可以創(chuàng)建的對(duì)象可以節(jié)省內(nèi)存空間,并且無(wú)需復(fù)制,提高查詢速度
在視圖中,創(chuàng)建的對(duì)象如果修改數(shù)據(jù),原始數(shù)據(jù)也被修改。
3. 副本
副本概念
副本是對(duì)原數(shù)組進(jìn)行完整拷貝(數(shù)據(jù)地址也會(huì)拷貝新的),與原始數(shù)組完全獨(dú)立,相對(duì)于“深拷本”,不與原始數(shù)組共享數(shù)據(jù)。
同樣截取官網(wǎng),對(duì)副本的描述:
Deep Copy The copy method makes a complete copy of the array and its data
當(dāng)改變副本的數(shù)據(jù)元素值時(shí),雖然改變了副本與原數(shù)組相互獨(dú)立,原始數(shù)組中元素值不會(huì)發(fā)生改變。
副本應(yīng)用
- 當(dāng)進(jìn)行切片操作時(shí)
- 當(dāng)需要與原始數(shù)組數(shù)據(jù)獨(dú)立時(shí)
副本的實(shí)現(xiàn)我們可以直接使用 ndarray.copy()
方法對(duì)原數(shù)組進(jìn)行深拷貝
b = np.array([2,5,7]) c = b.copy() c[1] = 8 print("b:",b) print("c:",c) print("c is b:",c is b) # 查看 ndarray.base 屬性? print("b.base:",b.base) print("c.base:",c.base) # 查看 ndarray.flags.owndata print("b.flags.owndata:",b.flags.owndata) print("c.flags.owndata:",c.flags.owndata)
總結(jié):
本期,我們對(duì) numpy 模塊中重要的概念視圖和副本。
- 視圖,相當(dāng)于淺拷貝,與原數(shù)組共享數(shù)據(jù)。
- 副本,相當(dāng)于深拷貝,與原數(shù)組數(shù)據(jù)相互獨(dú)立
我們可以通過(guò)內(nèi)存地址id()方法,同時(shí)借助ndarray.base、ndarray.flags來(lái)進(jìn)一步分析區(qū)別
到此這篇關(guān)于Python numpy視圖與副本的文章就介紹到這了,更多相關(guān)Python numpy視圖與副本內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python subprocess模塊學(xué)習(xí)總結(jié)
從Python 2.4開始,Python引入subprocess模塊來(lái)管理子進(jìn)程,以取代一些舊模塊的方法:如 os.system、os.spawn*、os.popen*、popen2.*、commands.*不但可以調(diào)用外部的命令作為子進(jìn)程,而且可以連接到子進(jìn)程的input/output/error管道,獲取相關(guān)的返回信息2014-03-03學(xué)python需要去培訓(xùn)機(jī)構(gòu)嗎
在本篇文章里小編給大家整理的是關(guān)于學(xué)python是否需要去培訓(xùn)機(jī)構(gòu)的相關(guān)內(nèi)容,有需要的朋友們可以閱讀下。2020-07-07python?spotlight庫(kù)簡(jiǎn)化交互式方法探索數(shù)據(jù)分析
這篇文章主要為大家介紹了python?spotlight庫(kù)簡(jiǎn)化的交互式方法探索數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Pytorch深度學(xué)習(xí)之實(shí)現(xiàn)病蟲害圖像分類
PyTorch是一個(gè)開源的Python機(jī)器學(xué)習(xí)庫(kù),基于Torch,用于自然語(yǔ)言處理等應(yīng)用程序。它具有強(qiáng)大的GPU加速的張量計(jì)算和自動(dòng)求導(dǎo)系統(tǒng)的深度神經(jīng)網(wǎng)絡(luò)。本文將介紹如何通過(guò)PyTorch實(shí)現(xiàn)病蟲害圖像分類,感興趣的可以學(xué)習(xí)一下2021-12-12多個(gè)版本的python共存時(shí)使用pip的正確做法
這篇文章主要介紹了多版本python共存時(shí)使用pip的正確做法,幫助有多個(gè)python版本需求的人可以正確的導(dǎo)包,感興趣的朋友可以了解下2020-10-10Python設(shè)計(jì)模式結(jié)構(gòu)型組合模式
這篇文章主要介紹了Python設(shè)計(jì)模式結(jié)構(gòu)型組合模式,組合模式即Composite?Pattern,將對(duì)象組合成成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性,下文具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-02-02