如何将 panda.Series 与动态比较器进行比较?

How to compare panda.Series with a dynamic comparator?

我确实有一个可行的解决方案。我很高兴自己真的找到了一个。但是,似乎应该有一个我目前不知道的更好的方法?

我希望能够在将 panda.Series 与另一个 panda.Series 或标量进行比较时动态指定要使用的比较器。

我目前的解决方案

    import numpy as np
    import pandas as pd

    def func(data, values, shifts, comparator):
        _if   = comparator[0]( data.shift( shifts[0] ), values[0] )
        _then = comparator[1]( data.shift( shifts[1] ), values[1] )
        _else = comparator[2]( data.shift( shifts[2] ), values[2] )

        return data[ np.where(_if, _then, _else) ]

    if __name__ == '__main__':
        series = pd.Series([1, 1, 0, 1, 1, 1, -1, -1, 0, -1, 1, 1, 1])

        filter = series[ np.where(series == 0, series.shift(1) > 0, series > 0) ]

        filter2 = func(
                     data=series, 
                     values=[0,0,0], 
                     shifts=[0,1,0], 
                     comparator=[pd.Series.eq, pd.Series.gt, pd.Series.gt]
                       )

filterfilter2都给出完全相同的预期输出。我只是忍不住想有比我的自定义函数更好的方法,func()

代码解释:

series指随时间变化的随机游走数据。 1 是向上的一步,-1 是向下的一步,0 是保持不变。我写 func() 是为了能够找到数据何时上升或下降。我希望能够在尽可能少的代码中选择、寻找、升级或退出。

当我说 "version" 时,我指的是获得有用结果并将其放入 filterfilter2 的代码,在我看来这些是版本 1 和2分别。要扩展我的 "readability" 评论,请注意每个评论中有多少代码:

  1. 第一个版本只有一行代码,很明显它的每个部分在做什么以及为什么
  2. 使用func的版本涉及10行代码,认知负荷更高。我,代码的 reader,必须将大量状态穿入和穿出函数

举个例子,如果我想获取两个连续值 > 0 的值,天真的解决方案是:

series[(series > 0) & (series.shift(1) > 0)]

但是用func,虽然我觉得应该可以,但是我当然不能像上面那样轻松写出来。我想用 monte carlo 链做的更复杂的事情当然不能用它来表达

总的来说,我不鼓励您尝试编写 "generalized as possible" 代码,尤其是因为 "in future" 事情往往不会发生,或者至少发生的方式与您的 "general" 不同代码不够通用。也就是说,尝试 think/work 虽然像这样的练习确实有用,而且您一定会找到应用您的东西的方法 discovered/learned。尝试编写最通用的东西几乎总是一个错误,确定正确的抽象级别很难,需要大量的实践和经验

这种事情经常发生,甚至有一个术语来形容它:"You aren't gonna need it". there are lots of blog articles 说类似的话

希望有用,抱歉有点乱!