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