web-dev-qa-db-ja.com

python Pandas DataFrame copy(deep = False)vs copy(deep = True)vs '='

誰かが私に違いを説明してもらえますか

_df2 = df1

df2 = df1.copy()

df3 = df1.copy(deep=False)
_

すべてのオプションを試しましたが、次のようにしました。

_df1 = pd.DataFrame([1,2,3,4,5])
df2 = df1
df3 = df1.copy()
df4 = df1.copy(deep=False)
df1 = pd.DataFrame([9,9,9])
_

次のように返されます。

_df1: [9,9,9]
df2: [1,2,3,4,5]
df3: [1,2,3,4,5]
df4: [1,2,3,4,5]
_

したがって、.copy().copy(deep=False)の出力に違いはありません。どうして?

オプション '='、copy()、copy(deep = False)のいずれかが_[9,9,9]_を返すと予想されます

何が足りないのですか?

22
szerszen

作成したさまざまなDataFramesのオブジェクトIDを見ると、何が起こっているかを明確に見ることができます。

df2 = df1を記述する場合、df2という名前の変数を作成し、それをID 4541269200のオブジェクトにバインドします。 df1 = pd.DataFrame([9,9,9])と記述すると、ID 4541271120newオブジェクトを作成し、変数df1にバインドしますが、idのオブジェクトは以前に4541269200にバインドされていたdf1は存続します。そのオブジェクトにバインドされた変数がない場合、Pythonによってガベージコレクションが行われます。

In[33]: import pandas as pd
In[34]: df1 = pd.DataFrame([1,2,3,4,5])
In[35]: id(df1)
Out[35]: 4541269200

In[36]: df2 = df1
In[37]: id(df2)
Out[37]: 4541269200  # Same id as df1

In[38]: df3 = df1.copy()
In[39]: id(df3)
Out[39]: 4541269584  # New object, new id.

In[40]: df4 = df1.copy(deep=False)
In[41]: id(df4)
Out[41]: 4541269072  # New object, new id.

In[42]: df1 = pd.DataFrame([9, 9, 9])
In[43]: id(df1)
Out[43]: 4541271120  # New object created and bound to name 'df1'.

In[44]: id(df2)
Out[44]: 4541269200  # Old object's id not impacted.

編集:2018年7月30日に追加

ディープコピー pandasでは機能しません そして、開発者は、DataFrame内に可変パターンをアンチパターンとして配置することを検討します。以下を考慮してください。

In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]

df2、それが真のディープコピーである場合、その中に含まれるリストの新しいIDが必要でした。その結果、df2内のリストを変更すると、それらは同じオブジェクトであるため、df1内のリストにも影響します。

16
Karthik V

ディープコピーは、含まれるすべてのオブジェクトの新しいIDを作成しますが、通常のコピーは親から要素をコピーするだけで、コピー先の変数の新しいIDを作成します。

df2df3、およびdf4[9,9,9]を表示しない理由は次のとおりです。

In[33]: import pandas as pd
In[34]: df1 = pd.DataFrame([1,2,3,4,5])
In[35]: id(df1)
Out[35]: 4541269200

In[36]: df2 = df1
In[37]: id(df2)
Out[37]: 4541269200  # Same id as df1

In[38]: df3 = df1.copy()
In[39]: id(df3)
Out[39]: 4541269584  # New object, new id.

In[40]: df4 = df1.copy(deep=False)
In[41]: id(df4)
Out[41]: 4541269072  # New object, new id.

In[42]: df1 = pd.DataFrame([9, 9, 9])
In[43]: id(df1)
Out[43]: 4541271120  # New object created and bound to name 'df1'.
3
Aman Agrawal

Dfの要素を個別に変更する必要があります。以下をお試しください

df1 = pd.DataFrame([1,2,3,4,5])
df2 = df1
df3 = df1.copy()
df4 = df1.copy(deep=False)

df1.iloc[0,0] = 6
df2.iloc[1,0] = 7
df4.iloc[2,0] = 8

print(df1)
print(df2)
print(df3)
print(df4)
0
flysoon