webentwicklung-frage-antwort-db.com.de

python Pandas DataFrame-Kopie (tief = falsch) vs. Kopie (tief = wahr) vs.

Könnte mir jemand einen Unterschied erklären?

df2 = df1

df2 = df1.copy()

df3 = df1.copy(deep=False)

Ich habe alle Optionen ausprobiert und habe folgendes gemacht:

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

und wie folgt zurückgegeben:

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

Ich beobachte also keinen Unterschied in der Ausgabe zwischen .copy() und .copy(deep=False). Warum? 

Ich würde eine der Optionen '=', copy (), copy (deep = False) erwarten, um [9,9,9] zurückzugeben.

Was fehlt mir bitte?

16
BlueTomato

Wenn Sie die Objekt-IDs der verschiedenen von Ihnen erstellten DataFrames sehen, können Sie deutlich sehen, was passiert. 

Wenn Sie df2 = df1 schreiben, erstellen Sie eine Variable mit dem Namen df2 und binden diese mit einem Objekt mit der ID 4541269200. Wenn Sie df1 = pd.DataFrame([9,9,9]) schreiben, erstellen Sie ein new - Objekt mit der ID 4541271120 und binden es an die Variable df1. Das Objekt mit der ID 4541269200, das zuvor an df1 gebunden war, bleibt jedoch erhalten. Wenn an dieses Objekt keine Variablen gebunden waren, wird von Python Müll gesammelt.

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.

Edit: Hinzugefügt am 30.07.2014

Tiefes Kopieren funktioniert nicht in Pandas und die Entwickler ziehen es in Betracht, veränderliche Objekte als Gegenmuster in einen DataFrame zu stellen. Folgendes berücksichtigen:

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, wenn es sich um eine echte tiefe Kopie handelt, sollten neue IDs für die darin enthaltenen Listen vorhanden sein. Wenn Sie also eine Liste in df2 ändern, wirkt sich dies auch auf die Liste in df1 aus, da sie die gleichen Objekte sind.

13
Karthik V

Deep Copy erstellt neue IDs für jedes Objekt, während es bei normaler Kopie nur die Elemente aus dem übergeordneten Element kopiert und eine neue ID für eine Variable erstellt, in die sie kopiert wird.

Der Grund für keines von df2, df3 und df4, der [9,9,9] anzeigt, lautet:

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'.
2
Aman Agrawal

Sie müssen die Elemente von df einzeln ändern. Versuche Folgendes

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