Python 查询pandas copy()方法

Python 查询pandas copy()方法,python,pandas,Python,Pandas,修改df1时,不修改对象sf2。我期待它,因为我使用了copy() 但是为什么在这种情况下,s2也发生了变化?我不希望对s2进行任何更改,因为我使用了copy()来创建它,但出乎意料的是,在修改s1时,对象s2也被修改了。我不明白为什么。之所以发生这种情况,是因为您的pd.Series是dtype=object,所以它实际上复制了一系列对python对象的引用。注意: s1=pd.Series([[1,2],[3,4]]) s2=s1.copy() s1[0][0]=0 #modifying t

修改
df1
时,不修改对象
sf2
。我期待它,因为我使用了
copy()


但是为什么在这种情况下,
s2
也发生了变化?我不希望对
s2
进行任何更改,因为我使用了
copy()
来创建它,但出乎意料的是,在修改
s1
时,对象
s2
也被修改了。我不明白为什么。

之所以发生这种情况,是因为您的
pd.Series
是dtype=object,所以它实际上复制了一系列对python对象的引用。注意:

s1=pd.Series([[1,2],[3,4]])
s2=s1.copy()
s1[0][0]=0 #modifying the 1st element of list [1,2]
print s1
print s2
由于
list
对象是可变的,因此操作:

In [1]: import pandas as pd

In [2]: s1=pd.Series([[1,2],[3,4]])
   ...:

In [3]: s1
Out[3]:
0    [1, 2]
1    [3, 4]
dtype: object

In [4]: s1.dtype
Out[4]: dtype('O')
就地修改列表

这种行为是一种“浅复制”,通常情况下,它与数据结构无关,因为通常情况下,您将使用数字数据类型,在这种情况下浅复制不适用,或者如果您使用对象数据类型,则将使用python字符串对象,这些对象是不可变的

注意,
pandas
容器具有不同的深度副本概念。请注意,
.copy
方法有一个默认值
deep=True
,但从文档中可以看出:

deep=True
(默认值)时,将使用副本创建一个新对象 调用对象的数据和索引。对数据的修改或 副本的索引不会反映在原始对象中(请参见 注释如下)

deep=False
时,将创建一个新对象,而不复制 调用对象的数据或索引(仅引用数据和索引 (已复制)。原始数据的任何更改都将反映出来 在浅拷贝中(反之亦然)。。。当
deep=True
时,数据为 已复制但实际的Python对象不会被递归复制,仅 对对象的引用。这与中的
copy.deepcopy
形成对比 标准库,递归复制对象数据(请参见 下面的例子)


同样,这是因为
pandas
是为使用数字数据类型而设计的,内置了对
str
对象的支持。
pd.Series
对象的
pd.Series
列表确实非常奇怪,对于
pd.Series
来说,这并不是一个好的用例。当您复制
s1
对象时,它实际上创建了一个新的、单独的Series对象,并将其引用到
s2
——正如您所期望的那样。但是,
s1
Series对象中的两个列表没有与序列重复。它只是复制了他们的参考资料

有关了解Python
参考
对象
之间区别的良好起点,请参阅

简单地说,Python
变量
与实际的Python对象不同。变量(如
s1
s2
)只是指向实际对象所在内存位置的引用

由于原始序列对象
s1
包含两个列表引用,而不是两个列表对象,因此仅复制内部列表对象的
引用
(而不是列表对象本身)

输出:

import pandas as pd

s1=pd.Series([[1,2],[3,4]])
# The oject referenced by variable "s1" has a memory address
print ("s1:", hex(id(s1)))
s2=s1.copy()
# The oject referenced by variable "s2" has a different memory address
print ("s2:", hex(id(s2)))
# However when you copied "s1", the 
# list items within only had their references copied
# So "s1[0]" and "s2[0]" are simply references to the same object
print ("s1[0]:", hex(id(s1[0])))
print ("s2[0]:", hex(id(s2[0])))
@juanpa.arrivillaga的回答是正确的,你需要使用

s1[0][0]=0
import pandas as pd

s1=pd.Series([[1,2],[3,4]])
# The oject referenced by variable "s1" has a memory address
print ("s1:", hex(id(s1)))
s2=s1.copy()
# The oject referenced by variable "s2" has a different memory address
print ("s2:", hex(id(s2)))
# However when you copied "s1", the 
# list items within only had their references copied
# So "s1[0]" and "s2[0]" are simply references to the same object
print ("s1[0]:", hex(id(s1[0])))
print ("s2[0]:", hex(id(s2[0])))
s1: 0x7fcdf5678898 # A different address form s2
s2: 0x7fcddee25240 # A different address form s1
s1[0]: 0x7fcdddf9f6c8 # The same address for the first list
s2[0]: 0x7fcdddf9f6c8 # The same address for the first list