Pandas.apply依赖于前一个值(非shift)

1 投票
2 回答
1410 浏览
提问于 2025-05-10 09:56

我想对数据表中的每一行应用一个函数。问题是,这个函数需要上一行的输出作为输入。

我想使用这个函数

def emaIrregular(alpha, sample, sampleprime, deltats, emaprime):
  a = deltats / float(alpha)
  u = math.exp(a * -1)
  v = (1 - u) / a

  return (u * emaprime) + ((v - u) * prevprime) +((1.0 - v) * sample)

问题出在参数 emaprime 上,因为它是在计算当前的ema值。我知道我可以通过移动数据表来获取 sampleprimedeltats 的值。

我使用的函数有点复杂:这里有一个简单的例子,希望能帮助理解。

def myRollingSum(x, xprime):
  return x + xprime

这个函数类似于滚动求和,因为它使用上一轮的输出作为下一轮的输入。


编辑 好的,我的 myRollingSum 例子让大家有点困惑。我需要访问上一行的结果,但这个结果正是我正在计算的东西!也就是说,f(x_i) = f(x_i-1) + c。另外,这个过程有点像计算阶乘。

我的数据比较稀疏,并且分布不规则。对每个窗口重新采样或插值并在扩展的数据集上运行是不现实的。

我感觉除了逐条记录地处理,没有简单的方法来做到这一点?

相关文章:

  • 暂无相关问题
暂无标签

2 个回答

0

看起来你想用递归函数。这样的话,.rolling_apply 就不太适用了。有一种方法是把序列的值当成一个列表或者 numpy 数组。然后通过循环这个列表来使用递归函数。

你的函数应该是自己调用自己的,像这样。

def factorial(i, alist):
    if i > 0:
        print alist[i-1]
        return alist[i]*factorial(i-1,alist)
    else:
        return 1

如果你想通过数据框来实现,可以先创建一个包含所有序列值的列表。然后再创建一个包含索引号的列表。接着你可以用 numpy.vectorize 来调用阶乘函数(或者你自己的函数)。

df["alldata"] = df["x"].values().tolist()
df = df.reset_index()
# 
df["fact"] = numpy.vectorize(factorial)(df["index"], df["alldata"])

我觉得这个方法的执行速度可能会比使用 iterrows() 快,但我不太确定。

0

看起来 .rolling_apply 确实可以像 behzad.nouri 提到的那样使用。

还有一种更简单但可能更容易理解的方法,就是用 .shift(1) 来创建一个 移位 的列。然后,可以使用 numpy 的 vectorize 函数,利用这两列作为输入来调用一个函数。

df['shifted'] = df["x"].shift(1)
def myRollingSum(x, xprime):
  return x + xprime
df['rsum'] = np.vectorize(myRollingSum)(df['x'], df['shifted'])

撰写回答