根据 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/

10-16 16:26