当从父数据帧中选择子数据帧时,我注意到一些程序员使用.copy()方法来复制数据帧。例如,
X = my_dataframe[features_list].copy()
...而不仅仅是
X = my_dataframe[features_list]
他们为什么要复制数据帧?如果我不复制一份会怎么样?
当从父数据帧中选择子数据帧时,我注意到一些程序员使用.copy()方法来复制数据帧。例如,
X = my_dataframe[features_list].copy()
...而不仅仅是
X = my_dataframe[features_list]
他们为什么要复制数据帧?如果我不复制一份会怎么样?
当前回答
假设您有如下数据帧
df1
A B C D
4 -1.0 -1.0 -1.0 -1.0
5 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
当你想创建另一个df2,它是相同的df1,没有复制
df2=df1
df2
A B C D
4 -1.0 -1.0 -1.0 -1.0
5 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
并想修改df2值仅如下所示
df2.iloc[0,0]='changed'
df2
A B C D
4 changed -1.0 -1.0 -1.0
5 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
同时df1也被改变了
df1
A B C D
4 changed -1.0 -1.0 -1.0
5 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
由于两个df是同一个对象,我们可以使用id来检查它
id(df1)
140367679979600
id(df2)
140367679979600
所以它们是同一个对象,一个改变另一个也会传递相同的值。
如果我们添加副本,现在df1和df2被认为是不同的对象,如果我们对其中一个做相同的改变,另一个将不会改变。
df2=df1.copy()
id(df1)
140367679979600
id(df2)
140367674641232
df1.iloc[0,0]='changedback'
df2
A B C D
4 changed -1.0 -1.0 -1.0
5 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
值得一提的是,当您对原始数据帧进行子集时,添加副本也是安全的,以避免SettingWithCopyWarning
其他回答
有必要提到,返回副本或视图取决于索引的类型。
熊猫的文件说:
返回一个视图和一个副本 关于何时返回数据视图的规则完全是 取决于NumPy。每当一个标签数组或布尔向量 都涉及到索引操作,结果将是一个副本。 使用单标签/标量索引和切片,例如df。第九[3:6]或 df。ix[:, 'A'],将返回一个视图。
在使用copy()之前,我非常粗心,直到使用下面这行代码 如果不使用copy(), df_genel3中的更改会影响df_genel
df_genel3 = df_genel
df_genel3.loc[(df_genel3['Hareket']=='İmha') , 'Hareket_Tutar'] = tutar
Copy()解决了这个问题
df_genel3 = df_genel.copy()
df_genel3.loc[(df_genel3['Hareket']=='İmha') , 'Hareket_Tutar'] = tutar
因为如果你不复制,那么即使你把dataFrame赋给一个不同的名字,索引仍然可以在其他地方被操纵。
例如:
df2 = df
func1(df2)
func2(df)
Func1可以通过修改df2来修改df,为了避免:
df2 = df.copy()
func1(df2)
func2(df)
假设您有如下数据帧
df1
A B C D
4 -1.0 -1.0 -1.0 -1.0
5 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
当你想创建另一个df2,它是相同的df1,没有复制
df2=df1
df2
A B C D
4 -1.0 -1.0 -1.0 -1.0
5 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
并想修改df2值仅如下所示
df2.iloc[0,0]='changed'
df2
A B C D
4 changed -1.0 -1.0 -1.0
5 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
同时df1也被改变了
df1
A B C D
4 changed -1.0 -1.0 -1.0
5 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
由于两个df是同一个对象,我们可以使用id来检查它
id(df1)
140367679979600
id(df2)
140367679979600
所以它们是同一个对象,一个改变另一个也会传递相同的值。
如果我们添加副本,现在df1和df2被认为是不同的对象,如果我们对其中一个做相同的改变,另一个将不会改变。
df2=df1.copy()
id(df1)
140367679979600
id(df2)
140367674641232
df1.iloc[0,0]='changedback'
df2
A B C D
4 changed -1.0 -1.0 -1.0
5 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
6 -1 -1.0 -1.0 -1.0
值得一提的是,当您对原始数据帧进行子集时,添加副本也是安全的,以避免SettingWithCopyWarning
一般来说,在副本上工作比在原始数据帧上工作更安全,除非您知道不再需要原始数据并希望继续使用修改过的版本。通常情况下,您仍然可以将原始数据帧与经过处理的版本进行比较,等等。因此,大多数人都在复制,最后合并。