如何使访问器类像熊猫一样?

时间:2019-08-07 17:42:51

标签: python python-3.x pandas

我有一类具有很多方法的类,这些方法在逻辑上可以分组。我想像在pandas中将它们分组。例如,在熊猫中,所有绘制方法都可以通过df.plot访问,即df.plot.hist(...)df.plot.bar(...)。滚动方法也可以像df.rolling(2).sum()一样分组和访问。

我查看了pandas的源代码,但没有帮助。

如何为我的自定义类实现诸如.plot.<plot method>.normalize.<normalize method>.smooth.<smooth method>等中间访问器类?

1 个答案:

答案 0 :(得分:2)

这是一个非常基本的实现:

>>> class FancyPlotting:
...     def __init__(self, info: dict):
...         self.info = info
...     def plot(self, *args):
...         ... # use `self.info` and `args` to decide what and how to plot
...         
>>> class FancyDataframe:
...     def __init__(self, data: list):
...         self.data = data
...     def rolling(self, number: int):
...         return FancyRoller(self.data, number)
...     @property
...     def plot(self):
...         return FancyPlotting({'points': self.data})
...
>>> class FancyRoller:
...     def __init__(self, data: list, window_length: int):
...         self.data, self.window_length = data, window_length
...     def sum(self):
...         return sum(self.data[::self.window_length]) # this is not an actual implementation
...          
>>> df = FancyDataframe([1,2,3,4,5,6,7,8])
>>> df.plot.plot()
# does stuff
>>> df.rolling(1).sum()
36

当然,阅读熊猫的资料应该可以使您更好地了解这样做的方式。

编辑: Python不会不必要地复制数据,因此过多的内存使用不是问题:

class FancyRoller:
    def __init__(self, data: list, **settings):
        self.data, self.settings = data, settings

    def sum(self):
        return sum(self.data[::self.settings['size']])

class FancyDataframe:
    def __init__(self, data):
        self.data = data

    def rolling(self, size):
        # again, this is just an example
        return FancyRoller(self.data, size=size)

df = FancyDataframe([1,2,3,4,5,6,7])
assert id(df.data) == id(df.rolling(2).data)
print(df.rolling(1).sum())