Python pandas:子类系列和数据帧

时间:2017-09-20 08:06:16

标签: python pandas

我想为pandas SeriesDataFrames添加新的方法和属性。这是一个非常简单的例子:我想要一个方法来计算一行与前一行之间的差异不是1的时间。

这是我到目前为止对pandas对象进行子类化的原因:

import pandas as pd

class Serie(pd.Series):

    def gaps(self):
        return (self.diff().fillna(1) != 1).sum()

class DataSet(pd.DataFrame):

    _constructor_sliced = Serie

但基于this answer,似乎我可以这样做:

def gaps(self):
    return (self.diff().fillna(1) != 1).sum()

pd.Series.gaps = gaps

它似乎同样有效!

In[1]: df = pd.DataFrame({'A':[1,2,4], 'B':[3,2,1]})
In[2]: df.A.gaps()
Out[2]: 1

现在的问题是:这种情况的最佳做法是什么?第二个选项看起来比子类化要简单得多,但我可能会遗漏一些东西......这样做有什么警告吗?或者也许我错过了其他选择。

1 个答案:

答案 0 :(得分:0)

一个非常简单的解决方案就是使用像gaps函数这样的函数,但将“self”重命名为“serie”:

def gaps(serie):
    return (serie.diff().fillna(1) != 1).sum()

它保持关注的清晰(你的代码与熊猫代码)。

它更具可读性:你不需要了解很多东西就能理解它是如何工作的。这很简单。

这不太令人惊讶:您的团队中的开发人员可能会花一些时间尝试在Pandas系列文档中搜索gap()文档而不是找到它,只是为了发现几个小时之后有人(您)猴子打了它。

这也是最短的解决方案。

它避免使用像_constructor_sliced这样的“私人”成员,这些成员的名称可能会在未来发生变化并破坏您的实施。

它避免了未来的冲突:下一个pandas版本包括Series对象中的gap方法怎么样?它不会直接破坏,​​但我会在你的团队中找到一个开发人员,想要使用“现在众所周知的.gap()”,不知道你“改变它”,并且很难调试它为什么不会根据文件工作。