提问人:Antonio Amador 提问时间:6/12/2023 最后编辑:YnjxsjmhAntonio Amador 更新时间:6/13/2023 访问量:72
如何为熊猫添加新属性。DataFrame 派生类?
How can I add new attributes to a pandas.DataFrame derived class?
问:
我想创建一个派生自略有不同的类。我将把一些额外的数据存储在新属性中,最后调用 .pandas.DataFrame
__init__()
DataFrame.__init__()
from pandas import DataFrame
class DataFrameDerived(DataFrame):
def __init__(self, *args, **kwargs):
self.derived = True
super().__init__(*args, **kwargs)
DataFrameDerived({'a':[1,2,3]})
此代码在创建新属性 () 时出现以下错误:self.derived = True
RecursionError:调用 Python 对象时超出了最大递归深度
答:
0赞
juanpa.arrivillaga
6/12/2023
#1
这是可能的,但实现对扩展不是很开放。事实上,官方文档建议使用替代方案。的实现很复杂,涉及各种混合蛋白的多重继承,而且,它使用各种属性设置/获取钩子,如 和 ,以提供语法糖,如 using 和 to work without using the syntax。如果你看一下堆栈跟踪,你可以看到有些事情正在发生:pd.DataFrame
__getattr__
__setattr__
df.some_column
df.some_colum = whatever
df['some_column']
__setattr__
RecursionError Traceback (most recent call last)
Cell In[1], line 8
5 self.derived = True
6 super().__init__(*args, **kwargs)
----> 8 DataFrameDerived({'a':[1,2,3]})
Cell In[1], line 5, in DataFrameDerived.__init__(self, *args, **kwargs)
4 def __init__(self, *args, **kwargs):
----> 5 self.derived = True
6 super().__init__(*args, **kwargs)
File ~/miniconda3/envs/py311/lib/python3.11/site-packages/pandas/core/generic.py:6014, in NDFrame.__setattr__(self, name, value)
6012 else:
6013 try:
-> 6014 existing = getattr(self, name)
6015 if isinstance(existing, Index):
6016 object.__setattr__(self, name, value)
File ~/miniconda3/envs/py311/lib/python3.11/site-packages/pandas/core/generic.py:5986, in NDFrame.__getattr__(self, name)
5976 """
5977 After regular attribute access, try looking up the name
5978 This allows simpler access to columns for interactive use.
5979 """
5980 # Note: obj.x will always call obj.__getattribute__('x') prior to
5981 # calling obj.__getattr__('x').
5982 if (
5983 name not in self._internal_names_set
5984 and name not in self._metadata
5985 and name not in self._accessors
-> 5986 and self._info_axis._can_hold_identifiers_and_holds_name(name)
5987 ):
5988 return self[name]
5989 return object.__getattribute__(self, name)
知道了这一点,人们可能会盲目地使用来绕过这一点:object.__setattr__
In [1]: from pandas import DataFrame
...:
...: class DataFrameDerived(DataFrame):
...: def __init__(self, *args, **kwargs):
...: object.__setattr__(self, 'derived', True)
...: super().__init__(*args, **kwargs)
...:
...: DataFrameDerived({'a':[1,2,3]})
Out[1]:
a
0 1
1 2
2 3
但同样,在没有真正理解实现的情况下,你只是交叉手指并希望“它有效”。它可能。但正如链接文档中所述,您可能还需要重写“构造函数”方法,以便您的数据帧类型在使用 DataFrame 方法时将返回其自身类型的数据帧。
另一种方法是注册其他访问器命名空间,而不是使用继承。如果适合您,这是一种更简单的扩展熊猫的方法。
如果不了解您到底要完成什么的更多细节,就很难提出最佳的前进方向。但是你绝对应该从阅读我在扩展 Pandas 上链接到的所有文档开始
评论
0赞
Antonio Amador
6/13/2023
谢谢!官方文档链接非常有用
评论