簡體   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