首页 > 解决方案 > 如何复制包含列表的 pandas 数据框,以便将来对副本中列表的更改不会改变原始列表

问题描述

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 都给出相同的结果。如何在副本中避免这种“连锁效应”?或者有没有办法制作数据框的“更深”副本

标签: pythonpandascopy

解决方案


所以我找到了一个解决方法:

首先制作b一个新的数据框并从数据框 a 复制列b。然后创建了一个空列a

b=pd.DataFrame()
b["b"]=a["b"]
b["a"]=None

现在我们可以遍历数据框的行b并复制列a的值a。请注意,我们将类型设置为对象,以便我们可以将列表分配给数据框的条目,否则将抛出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. 我申请后使用了id函数copy,结果是:

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)


推荐阅读