如何比较熊猫.带动态比较器的串联?



我确实有一个可行的解决方案。我对自己真正找到一个感到相当满意。但是,似乎应该有我目前不知道的更好的方法?

我希望能够在比较熊猫时动态指定使用哪个比较器。系列到另一只熊猫。系列或标量。

我当前的解决方案

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()是为了能够找到数据何时上升或下降。我希望能够在尽可能少的代码中进行选择、寻找、提升或降级。

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

  1. 第一个版本有一行代码,很明显它的每个部分都在做什么以及为什么
  2. 使用func的版本涉及 10 行代码,并且具有更高的认知负荷。我,代码的读者,必须将大量状态线程化到函数中和函数之外

例如,如果我想获取两个连续值> 0 的值,朴素的解决方案将是:

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

但是使用func,虽然我认为应该是可能的,但我肯定不能像上面那样容易地写它。 我想用蒙特卡洛链条做的更复杂的事情当然不能用它来表达

一般来说,我不鼓励你尝试编写"尽可能通用"的代码,特别是因为"将来"的事情往往不会发生,或者至少以不同的方式发生,以至于你的"通用"代码不够通用。 也就是说,尝试思考/工作这样的练习确实有用,你肯定会找到应用你发现/学到的东西的方法。 尝试编写最一般的东西几乎总是一个错误,确定正确的抽象级别很困难,需要大量的实践和经验

这种事情发生得足够多,甚至有一个术语:"你不需要它"。 有很多博客文章说类似的事情

希望有用,对不起,有点漫无边际!

最新更新