繁体   English   中英

如何复制包含列表的 Pandas 数据框,以便将来对副本中列表的更改不会改变原始列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM