真正深度复制 Pandas DataFrames
Truly deep copying Pandas DataFrames
我遇到了一些我觉得很奇怪的事情:显然不可能真正深度复制 pandas 数据帧。
我希望,如果我创建一个数据帧的深层副本,并且我修改了这个副本中的数据,它不会影响原始数据帧。但显然情况并非如此,如果我没记错的话甚至是可能的。
重现代码:
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'
我的问题是:
- 是否可以创建 pandas 数据帧的真正深层副本?
- 如果不是为什么?如果是,怎么做?
一种方法是将 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)
输出:
0 {1}
Name: sets, dtype: object
0 {1}
Name: sets, dtype: object
0 {1}
Name: sets, dtype: object
问题是您的对象是可变的,因为它们是集合。 documents 明确指出此行为并发出警告(强调我自己的):
When deep=True, data is copied but actual Python objects will not be copied recursively, only the reference to the 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
我遇到了一些我觉得很奇怪的事情:显然不可能真正深度复制 pandas 数据帧。
我希望,如果我创建一个数据帧的深层副本,并且我修改了这个副本中的数据,它不会影响原始数据帧。但显然情况并非如此,如果我没记错的话甚至是可能的。
重现代码:
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'
我的问题是:
- 是否可以创建 pandas 数据帧的真正深层副本?
- 如果不是为什么?如果是,怎么做?
一种方法是将 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)
输出:
0 {1}
Name: sets, dtype: object
0 {1}
Name: sets, dtype: object
0 {1}
Name: sets, dtype: object
问题是您的对象是可变的,因为它们是集合。 documents 明确指出此行为并发出警告(强调我自己的):
When deep=True, data is copied but actual Python objects will not be copied recursively, only the reference to the 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