[英]How can I copy a pandas dataframe that contains a list, so that future changes to the list in the copy will not alter the original one
a = pd.DataFrame({'a': [[1,1],[2, 2],[3,3]], 'b':[3,2,1]})
a b
0 [1, 1] 3
1 [2, 2] 2
2 [3, 3] 1
在制作一个深拷贝之后
b = copy.deepcopy(a)
更改 b 中的第一个列表元素
b.a[0][0] = 0
a b
0 [0, 1] 3
1 [2, 2] 2
2 [3, 3] 1
还会更改列表中的
a
a b
0 [0, 1] 3
1 [2, 2] 2
2 [3, 3] 1
df.copy 和 copy.deepcopy 都给出了相同的结果。 如何在副本中避免这种“连锁效应”? 或者有没有办法制作数据帧的“更深”副本
所以我找到了一个解决方法:
首先使b
成为一个新的数据框并从数据框 a 中复制列b
。 然后创建一个空列a
。
b=pd.DataFrame()
b["b"]=a["b"]
b["a"]=None
现在我们可以遍历b
的行并从数据帧a
复制列a
的值。 请注意,我们将类型设置为 object 以便我们可以将列表分配给数据框的条目,否则将抛出ValueError
b =b.astype(object)
for i in range(len(b)):
b.loc[i,"a"]=copy.deepcopy(a.loc[i,"a"])
然后进行所需的更改:
b.a[0][0] = 0
现在我们有b
:
b a
0 3 [0, 1]
1 2 [2, 2]
2 1 [3, 3]
和a
保持不变
a b
0 [1, 1] 3
1 [2, 2] 2
2 [3, 3] 1
现在让我们看看使用copy
可能存在的问题。 我在应用copy
后使用了id函数,结果是:
b=copy.copy(a)
print(id(a)==id(b)) #False
print(id(a["a"])==id(b["a"])) #False
print(id(a.loc[0,"a"])==id(b.loc[0,"a"])) #True
由于列 a 中有列表,两个数据框都引用同一个列表,修改一个会影响另一个。 这是一个一个地迭代复制列表背后的直觉。 请注意,即使使用b=copy.deepcopy(a)
也能看到相同的结果
2年前我问过这个问题。 在 Pandas 和数据争论中经历了几年之后,我发现在 Pandas 数据帧中不使用可变数据结构始终是最佳实践。 因此,如果我再次这样做,我会使用Tuple
而不是List
,这样突变就不再适用了。 因此,问题中的“复制”问题不是一回事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.