我想为pandas Series
和DataFrames
添加新的方法和属性。这是一个非常简单的例子:我想要一个方法来计算一行与前一行之间的差异不是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
现在的问题是:这种情况的最佳做法是什么?第二个选项看起来比子类化要简单得多,但我可能会遗漏一些东西......这样做有什么警告吗?或者也许我错过了其他选择。
答案 0 :(得分:0)
一个非常简单的解决方案就是使用像gaps
函数这样的函数,但将“self”重命名为“serie”:
def gaps(serie):
return (serie.diff().fillna(1) != 1).sum()
它保持关注的清晰(你的代码与熊猫代码)。
它更具可读性:你不需要了解很多东西就能理解它是如何工作的。这很简单。
这不太令人惊讶:您的团队中的开发人员可能会花一些时间尝试在Pandas系列文档中搜索gap()
文档而不是找到它,只是为了发现几个小时之后有人(您)猴子打了它。
这也是最短的解决方案。
它避免使用像_constructor_sliced
这样的“私人”成员,这些成员的名称可能会在未来发生变化并破坏您的实施。
它避免了未来的冲突:下一个pandas版本包括Series对象中的gap方法怎么样?它不会直接破坏,但我会在你的团队中找到一个开发人员,想要使用“现在众所周知的.gap()”,不知道你“改变它”,并且很难调试它为什么不会根据文件工作。