为什么不能通过副本传递实例的属性?我想将该name属性传递给另一个数据帧.
import copy
df = pd.DataFrame([1,2,3])
df.name = 'sheet1'
df2 = copy.deepcopy(df)
print(f'df.name: {df.name}')
>> df.name: sheet1
print(f'df2.name: {df2.name}')
>> AttributeError
...
'DataFrame' object has no attribute 'name'
Run Code Online (Sandbox Code Playgroud)
同样,在创建类并从中继承时,为什么这也不起作用?
class DfWithName(pd.DataFrame):
def __init__(self, *args, **kwargs):
self.__init__ = super().__init__(*args, **kwargs)
print('lol')
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
Run Code Online (Sandbox Code Playgroud)
并使用相同的代码:
import copy
df = DfWithName([1,2,3])
df.name = 'sheet1'
df2 = copy.deepcopy(df)
print(f'df.name: {df2.name}')
>> AttributeError
...
'DataFrame' object has no attribute 'name'
Run Code Online (Sandbox Code Playgroud)
如其他地方所述,DataFrame该类具有自定义__deepcopy__方法,该方法不一定复制分配给实例的任意属性,如同普通对象一样.
有趣的是,有一个内部_metadata属性似乎能够列出NDFrame复制/序列化时应保留的其他属性.这里有一些讨论:https://github.com/pandas-dev/pandas/issues/9317
不幸的是,这仍然被认为是未记录的内部细节,因此可能不应该使用它.通过查看代码,您原则上可以:
mydf = pd.DataFrame(...)
mydf.name = 'foo'
mydf._metadata += ['name']
Run Code Online (Sandbox Code Playgroud)
当你复制它时,它应该带有它的名字.
您可以将子类化为DataFrame默认值:
import functools
class NamedDataFrame(pd.DataFrame):
_metadata = pd.DataFrame._metadata + ['name']
def __init__(self, name, *args, **kwargs):
self.name = name
super().__init__(*args, **kwargs)
@property
def _constructor(self):
return functools.partial(self.__class__, self.name)
Run Code Online (Sandbox Code Playgroud)
_metadata如果您为现有copy方法提供自己的包装器,并且可能还有__getstate__,那么您也可以在不依赖此内部属性的情况下执行此操作__setstate__.
更新:它实际上似乎使用的_metadata属性用于扩展熊猫班现在记录.所以上面的例子应该或多或少有效.这些文档更多用于开发Pandas本身,因此它可能仍然有点不稳定.但这就是熊猫本身如何扩展子类的NDFrame.
| 归档时间: |
|
| 查看次数: |
1300 次 |
| 最近记录: |