python 淺拷貝 深拷貝 Dataframe

一、前言

?? 寫程序?qū)懙亩嗔耍瑫?huì)經(jīng)常發(fā)現(xiàn)很多寫法的隨意和不正規(guī)。比如,a=[1,2] ;b=a;
隨后對a的操作是否會(huì)給b造成同樣的影響呢?(反過來也一樣)。說的官方點(diǎn)的話,就是我們用b=a 這樣賦值,到底是在引用還是在復(fù)制

二、理論部分

2.1、賦值、引用

在python中賦值語句總是建立對象的引用值,而不是復(fù)制對象。因此,python變量更像是指針,而不是數(shù)據(jù)存儲區(qū)域。

  • 2.1.1 先用個(gè)例子,來看
a=[1,2,3]
b=a
a[0]=2
print(a)
print(b)

兩個(gè)輸出的結(jié)果都是[2,2,3]
就是說在簡單b=a 操作之后,一個(gè)對象中賦值的操作也會(huì)對另一個(gè)引起影響。這其實(shí)是引用而不是復(fù)制。

  • 2.2 可變對象&不可變對象
    在Python中,對象分為兩種:可變對象和不可變對象,不可變對象包括int,float,long,str,tuple等,可變對象包括list,set,dict等。需要注意的是:這里說的不可變指的是值的不可變。對于不可變類型的變量,如果要更改變量,則會(huì)創(chuàng)建一個(gè)新值,把變量綁定到新值上,而舊值如果沒有被引用就等待垃圾回收。另外,不可變的類型可以計(jì)算hash值,作為字典的key。可變類型數(shù)據(jù)對對象操作的時(shí)候,不需要再在其他地方申請內(nèi)存,只需要在此對象后面連續(xù)申請(+/-)即可,也就是它的內(nèi)存地址會(huì)保持不變,但區(qū)域會(huì)變長或者變短。
    說成人話,就是在python里面實(shí)打?qū)嵉臄?shù)才會(huì)占地方(內(nèi)存),比較高級點(diǎn)的對象都是在引用這些地方的位置(指針)

舉個(gè)簡單例子


舉個(gè)例子.png

舉個(gè)函數(shù)的例子


函數(shù)例子.png

對于上面的輸出,不少Python初學(xué)者都比較疑惑:第一個(gè)例子看起來像是傳值,而第二個(gè)例子確實(shí)傳引用。其實(shí),解釋這個(gè)問題也非常容易,主要是因?yàn)榭勺儗ο蠛筒豢勺儗ο蟮脑颍簩τ诳勺儗ο螅瑢ο蟮牟僮鞑粫?huì)重建對象,而對于不可變對象,每一次操作就重建新的對象。

三、重要應(yīng)用

3.1、深拷貝deepcopy與淺拷貝copy(python)

python中的對象之間賦值時(shí)是按引用傳送的,如果需要拷貝對象,需要使用標(biāo)準(zhǔn)庫中的copy模塊

1、copy.copy 淺拷貝,只拷貝父對象,不會(huì)拷貝對象的內(nèi)部的子對象。(子對象(數(shù)組)修改,也會(huì)修改)

2、copy.deepcopy 深拷貝,拷貝對象及其子對象(原始對象)


import copy
a=[1,2,[3,4],{'a':1}]   # 原始對象
b=a     # 賦值,傳對象的引用
c=copy.copy(a)  # 對象拷貝,淺拷貝
d=copy.deepcopy(a)  # 對象拷貝,深拷貝
e=a[:]  # 能復(fù)制序列,淺拷貝
 
a.append('add1')  # 修改對象a
a[2].append('add2')  # 修改對象a中的[3,4]數(shù)組對象
a[3]='666'
print('a:',a)
print('b:',b)
print('c:',c)
print('d:',d)

結(jié)果.png

3.2、深拷貝deepcopy與淺拷貝copy(dataframe)

DataFrame.copy(deep=True)

復(fù)制此對象的索引和數(shù)據(jù)。

當(dāng)deep=True(默認(rèn))時(shí),將使用調(diào)用對象的數(shù)據(jù)和索引的副本創(chuàng)建新對象。對副本的數(shù)據(jù)或索引的修改不會(huì)反映在原始對象中(請參閱下面的注釋)。

當(dāng)deep=False,將創(chuàng)建一個(gè)新對象而不復(fù)制調(diào)用對象的數(shù)據(jù)或索引(僅復(fù)制對數(shù)據(jù)和索引的引用)。對原始數(shù)據(jù)的任何更改都將反映在淺層副本中(反之亦然)。

類型 備注
參數(shù) deep ,bool,默認(rèn)為True 創(chuàng)建深層副本,包括數(shù)據(jù)和索引的副本。隨著deep=False無論是指數(shù)還是數(shù)據(jù)復(fù)制。
返回 Series,DataFrame 對象類型與調(diào)用者匹配。
>>> s = pd.Series([1, 2], index=["a", "b"])
>>> s
a    1
b    2
dtype: int64
>>> s_copy = s.copy()
>>> s_copy
a    1
b    2
dtype: int64

參考文獻(xiàn)

1、python 部分
2、Dataframe 拷貝

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。