我试图了解复制pandas数据框的工作原理。当我在python中分配对象的副本时,我不习惯更改影响该对象副本的原始对象。例如:
x = 3
y = x
x = 4
print(y)
3
当x
随后被更改时,y保持不变。相反,当我将pandas df
分配给副本df1
后对其进行更改时,副本也会受到原始DataFrame更改的影响。
import pandas as pd
import numpy as np
def minusone(x):
return int(x) - 1
df = pd.DataFrame({"A": [10,20,30,40,50], "B": [20, 30, 10, 40, 50], "C": [32, 234, 23, 23, 42523]})
df1 = df
print(df1['A'])
0 10
1 20
2 30
3 40
4 50
Name: A, dtype: int64
df['A'] = np.vectorize(minusone)(df['A'])
print(df1['A'])
0 9
1 19
2 29
3 39
4 49
Name: A, dtype: int64
解决方案似乎是使用copy.deepcopy()
进行深层复制,但由于此行为与我在python中习惯的行为不同,我想知道是否有人可以解释这种差异背后的原因是什么或是否这是一个错误。
答案 0 :(得分:8)
在您的第一个示例中,您未对x
的值进行更改。您已将新值分配给x
。
在第二个示例中,您确实修改了df
的值,方法是更改其中一列。
你也可以看到内置类型的效果:
>>> x = []
>>> y = x
>>> x.append(1)
>>> y
[1]
这种行为并非特定于熊猫;它是Python的基础。关于同样的问题,这个网站上有很多很多问题,都源于同样的误解。语法
barename = value
与Python中的任何其他构造没有相同的行为。
使用name[key] = value
或name.attr = value
或name.methodcall()
时,您可能会改变name
引用的对象的值,您可能正在复制某些内容等。通过使用name = value
(其中name
是单个标识符,没有点,没有括号等),您永远不会改变任何内容,也不会复制任何内容。
在第一个示例中,您使用了语法x = ...
。在第二个示例中,您使用了语法df['A'] = ...
。这些语法不同,因此您不能假设它们具有相同的行为。
制作副本的方式取决于您尝试复制的对象类型。对于您的情况,请使用df1 = df.copy()
。