在复制之后但在编辑复制之前编辑原始DataFrame会更改复制

Mic*_*ael 4 python numpy pandas

我试图了解如何复制pandas数据框.当我在python中分配对象的副本时,我不习惯更改影响该对象副本的原始对象.例如:

x = 3
y = x
x = 4
print(y)
3
Run Code Online (Sandbox Code Playgroud)

虽然x随后发生了变化,但仍然保持不变.相反,当我将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
Run Code Online (Sandbox Code Playgroud)

该解决方案似乎正在制作深层副本copy.deepcopy(),但因为这种行为与我在python中习惯的行为不同,我想知道是否有人可以解释这种差异背后的原因是什么,或者它是否是一个错误.

Bre*_*arn 8

在您的第一个示例中,您未对值进行更改x.您为其分配了一个新值x.

在第二个示例中,您df通过更改其中一个列来修改了值.

你也可以看到内置类型的效果:

>>> x = []
>>> y = x
>>> x.append(1)
>>> y
[1]
Run Code Online (Sandbox Code Playgroud)

这种行为并非特定于熊猫; 它是Python的基础.关于同样的问题,这个网站上有很多很多问题,都源于同样的误解.语法

barename = value
Run Code Online (Sandbox Code Playgroud)

与Python中的任何其他构造没有相同的行为.

当使用name[key] = value,或name.attr = value或者name.methodcall(),你可能会突变该对象的值称为通过name,则可以复制的东西等.通过使用name = value(其中name是一个单个标识符,没有点,没有托架等),则从未突变的任何,永远不要复制任何东西.

在第一个示例中,您使用了语法x = ....在第二个示例中,您使用了语法df['A'] = ....这些语法不同,因此您不能假设它们具有相同的行为.

制作副本的方式取决于您尝试复制的对象类型.对于您的情况,请使用df1 = df.copy().