簡體   English   中英

真正深拷貝 Pandas DataFrames

[英]Truly deep copying Pandas DataFrames

我遇到了一些我覺得很奇怪的事情:顯然,真正深度復制 pandas 數據幀是不可能的。

我希望,如果我創建 dataframe 的深層副本,並修改此副本中的數據,它不會影響原始 dataframe。 但顯然情況並非如此,如果我沒記錯的話,甚至是可能的。

重現代碼:

import pandas as pd

df = pd.DataFrame({'sets':set([1,2])}, index=[0])

def pop(df_in):
    df = df_in.copy()
    print(df['sets'].apply(lambda x: set([x.pop()])))

pop(df)
pop(df)
pop(df)

>>> KeyError: 'pop from an empty set'

或者

import copy
import pandas as pd

df = pd.DataFrame({'sets':set([1,2])}, index=[0])

def pop(df_in):
    df = copy.deepcopy(df_in)
    print(df['sets'].apply(lambda x: set([x.pop()])))

pop(df)
pop(df)
pop(df)

>>> KeyError: 'pop from an empty set'

我的問題是:

  1. 是否可以創建 pandas 數據幀的真正深層副本?
  2. 如果不是為什么? 如果是,如何?

一種方法是將df_in轉換為 Python 字典,它與copy一起使用效果更好:

def pop(df_in):
    df = pd.DataFrame(copy.deepcopy(df_in.to_dict()) )
    print(df['sets'].apply(lambda x: set([x.pop()])))

for i in range(3): pop(df)

Output:

0    {1}
Name: sets, dtype: object
0    {1}
Name: sets, dtype: object
0    {1}
Name: sets, dtype: object

問題是您的對象是可變的,因為它們是集合。 文件明確指出了這種行為並發出警告(強調我自己的):

當 deep=True 時,將復制數據,但不會遞歸復制實際的 Python 對象,僅復制對 object 的引用。

因此,與對可變對象的引用一樣,如果您更改它,它會在任何地方影響它。 盡管對象具有相同的 ID,但我們可以自己看到。

import pandas as pd
df = pd.DataFrame({'sets': [{1,2}]}, index=[0])
df1 = df.copy(deep=True)

id(df['sets'].iloc[0])
#4592957024

id1(df['sets'].iloc[0])
#4592957024

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM