我正在开发一个新的数据结构,它是pandas DataFrame的子类。我想强制我的新数据结构具有new_property,以便以后可以安全地处理它。 但是,在使用我的新数据结构时遇到了错误,因为构造函数被一些内部pandas函数调用而没有必需的属性。 这是我的新数据结构。
import pandas as pd
class MyDataFrame(pd.DataFrame):
@property
def _constructor(self):
return MyDataFrame
_metadata = ['new_property']
def __init__(self, data, new_property, index=None, columns=None, dtype=None, copy=True):
super(MyDataFrame, self).__init__(data=data,
index=index,
columns=columns,
dtype=dtype,
copy=copy)
self.new_property = new_property
以下是导致错误的示例
data1 = {'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [15, 25, 30], 'd': [1, 1, 2]}
df1 = MyDataFrame(data1, new_property='value')
df1[['a', 'b']]
以下是错误消息
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 2881, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-33-b630fbf14234>", line 1, in <module>
df1[['a', 'b']]
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\frame.py", line 2053, in __getitem__
return self._getitem_array(key)
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\frame.py", line 2098, in _getitem_array
return self.take(indexer, axis=1, convert=True)
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py", line 1670, in take
result = self._constructor(new_data).__finalize__(self)
TypeError: __init__() missing 1 required positional argument: 'new_property'
是否有解决方法或其他方法来设计此方法以强制我的新数据结构具有new_property?
提前致谢!
答案 0 :(得分:1)
这个问题已由一位出色的熊猫开发者回答。有关详细信息,请参阅this issue。在这里粘贴答案。
class MyDataFrame(pd.DataFrame):
@property
def _constructor(self):
return MyDataFrame._internal_ctor
_metadata = ['new_property']
@classmethod
def _internal_ctor(cls, *args, **kwargs):
kwargs['new_property'] = None
return cls(*args, **kwargs)
def __init__(self, data, new_property, index=None, columns=None, dtype=None, copy=True):
super(MyDataFrame, self).__init__(data=data,
index=index,
columns=columns,
dtype=dtype,
copy=copy)
self.new_property = new_property
data1 = {'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [15, 25, 30], 'd': [1, 1, 2]}
df1 = MyDataFrame(data1, new_property='value')
df1[['a', 'b']].new_property
Out[121]: 'value'
MyDataFrame(data1)
TypeError: __init__() missing 1 required positional argument: 'new_property'
答案 1 :(得分:0)
我知道这是一个老问题,但是我想扩展一下hlu的答案。
实现hlu描述的答案时,仅尝试打印子类化的DataFrame时出现以下错误:AttributeError: 'internal_constructor' object has no attribute '_from_axes'
要解决此问题,我使用了一个对象而不是hlu答案中使用的函数,以便能够在可调用对象上实现_from_axes
方法。
_internal_constructor类没有classmethod类型修饰符,因此我们使用调用者类实例化它,以便在调用_internal_constructor时可以使用它。
class MyDataFrame(pd.DataFrame):
@property
def _constructor(self):
return MyDataFrame._internal_constructor(self.__class__)
class _internal_constructor(object):
def __init__(self, cls):
self.cls = cls
def __call__(self, *args, **kwargs):
kwargs['my_required_argument'] = None
return self.cls(*args, **kwargs)
def _from_axes(self, *args, **kwargs):
return self.cls._from_axes(*args, **kwargs)