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