【问题标题】:copy and deepcopy are changing object typecopy 和 deepcopy 正在改变对象类型
【发布时间】:2019-08-15 15:43:54
【问题描述】:

我有以下例子:

import pandas as pd
from copy import copy, deepcopy

class DataFrameWrapper(pd.DataFrame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def __eq__(self, other):
        return self.equals(other)


t1 = DataFrameWrapper(pd.DataFrame({'a': [1, 2, 3]}))
t2 = deepcopy(t1)
t3 = copy(t1)

print(type(t1), ' ', type(t2), ' ', type(t3))

输出:

<class 'DataFrameWrapper'>   <class 'pandas.core.frame.DataFrame'>   <class 'pandas.core.frame.DataFrame'>

有谁能告诉我为什么 copy 和 deepcopy 会修改 t1 的类型?

DataFrameWrapper 类的目的只是让我在 pandas DataFrames 之间做一个==

【问题讨论】:

  • 为什么要两次调用DataFrame的构造函数?
  • @OlvinR​​oght 你是对的。你可以做t1 = DataFrameWrapper({'a': [1, 2, 3]}) 并得到我在我的问题中指出的同样的问题
  • @Taran 请检查我的回答,如果有帮助请点赞并接受。

标签: python pandas dataframe copy deep-copy


【解决方案1】:

发生这种情况是因为在 pandas 中重新定义了复制功能以返回基本类型。为了您的目的,您可以这样做:

class DataFrameWrapper(pd.DataFrame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def __eq__(self, other):
        return self.equals(other)

    def __copy__(self):
        return DataFrameWrapper(super().__copy__())

    def __deepcopy__(self, memo=None):
        return DataFrameWrapper(super().__deepcopy__(memo))

t1 = DataFrameWrapper(pd.DataFrame({'a': [1, 2, 3]}))
t2 = DataFrameWrapper(deepcopy(t1))
t3 = DataFrameWrapper(copy(t1))

您可以参考How to override the copy/deepcopy operations for a Python object? 了解定义 __copy__() 和 __deepcopy()__ 的工作原理,与在 pandas/core/generic.py 中的 pandas 库中所做的相同

为了测试上述理论(并用 pandas 重现行为),这里有一个测试代码:

from copy import copy, deepcopy

class Base:
    def __copy__(self):
        return Base()

    def __deepcopy__(self, memodict={}):
        return Base()


class Inherited(Base):
    pass


B = Base()
I = Inherited()
I_copy = copy(I)
I_deepcopy = deepcopy(I)

print('Type B :', type(B))
print('Type I :', type(I))
print('Type I_copy :', type(I_copy))
print('Type I_deepcopy :', type(I_deepcopy))

哪些输出:

Type B : <class '__main__.Base'>
Type I : <class '__main__.Inherited'>
Type I_copy : <class '__main__.Base'>
Type I_deepcopy : <class '__main__.Base'>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    相关资源
    最近更新 更多