如何使一个访问器类像在Pandas?

2024-04-24 23:11:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类,有很多方法,逻辑上可以分组。我想像在pandas中那样对它们进行分组。例如,在pandas中,所有绘图方法都可以通过df.plot访问,即df.plot.hist(...)df.plot.bar(...)。滚动方法也可以像df.rolling(2).sum()那样分组和访问

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

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


Tags: 方法绘图pandasdf源代码plotbar逻辑
1条回答
网友
1楼 · 发布于 2024-04-24 23:11:58

下面是一个非常基本的实现:

>>> 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())

相关问题 更多 >