根据 https://pandas.pydata.org/pandas-docs/stable/internals.html
我应该能够 sublcass Pandas 系列
我的 MCVE 是
from pandas import Series
class Xseries(Series):
_metadata = ['attr']
@property
def _constructor(self):
return Xseries
def __init__(self, *args, **kwargs):
self.attr = kwargs.pop('attr', 0)
super().__init__(*args, **kwargs)
s = Xseries([1, 2, 3], attr=3)
注意
attr
属性是:s.attr
3
但是,当我乘以
2
(s * 2).attr
0
这是默认设置。因此,没有传递
attr
。您可能会问,也许这不是预期的行为?我认为这是根据文档 https://pandas.pydata.org/pandas-docs/stable/internals.html#define-original-properties如果我们使用
mul
方法,它似乎有效s.mul(2).attr
3
而这不是(与
s * 2
相同)s.__mul__(2).attr
0
在我在 github 上创建问题之前,我想把它通过 SO。这是一个错误吗?
有解决方法吗?
我需要能够执行
s * 2
并将 attr
属性传递给结果。 最佳答案
如果你用 inspect.getsourcelines
去查看 mul
和 __mul__
这两个函数的源码,你会发现它们实际上有不同的实现。
并且使用 s.mul(2).attr
仍然不起作用,因为它只是使用 __finalize__
来传播所有属性,但并未真正将其相乘。
或者也许我误解了你的问题,你只是想传播而不是乘以 attr
?
如果是,您可以修改自定义 __mul__
函数以调用 __finalize__
。
from pandas import Series
class Xseries(Series):
_metadata = ['attr']
@property
def _constructor(self):
return Xseries
def __init__(self, *args, **kwargs):
self.attr = kwargs.pop('attr', 0)
super().__init__(*args, **kwargs)
def __mul__(self, other):
internal_result = super().__mul__(other)
return internal_result.__finalize__(self)
s = Xseries([1, 2, 3], attr=3)
如果没有,您可以手动乘以
attr
并返回。from pandas import Series
class Xseries(Series):
_metadata = ['attr']
@property
def _constructor(self):
return Xseries
def __init__(self, *args, **kwargs):
self.attr = kwargs.pop('attr', 0)
super().__init__(*args, **kwargs)
def __mul__(self, other):
internal_result = super().__mul__(other)
if hasattr(other, "attr"):
internal_result.attr = self.attr * other.attr
else:
internal_result.attr = self.attr * other
return internal_result
s = Xseries([1, 2, 3], attr=3)
关于python - 一些操作不尊重 Series 子类中的自定义属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46498784/