Pandas.apply依赖于先前的值(不是shift)

时间:2015-11-17 01:04:18

标签: python pandas time-series sparse-matrix moving-average

我正在尝试将函数应用于数据框中的每一行。问题是,该函数需要前一行的输出作为输入。

Wanting to use this function

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 ,因为这是计算当前的电子邮件值。我知道我可以将df转换为 sampleprime deltats 值。

我正在使用的功能有点复杂:这是一个玩具示例,我希望能帮到你。

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

所以类似于rollingsum,因为它使用前一次迭代的输出作为下一次迭代的输入。

修改的 好吧,myRollingSum的例子就是让人们失望。我需要访问上一行的结果,但这个结果是正在计算的东西!即f(x_i) = f(x_i-1) + c。或者,类似于因子换位的方式。

我的数据稀疏且间距不规则。对每个窗口重新采样/插值并遍历此扩展数据集是不可行的。

我觉得除了逐个迭代每个记录之外,没有一种简单的方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:0)

看起来.rolling_apply肯定会像behzad.nouri建议的那样工作

另一个愚蠢但可能更容易遵循的方法是使用.shift(1)来制作shifted列。 然后,使用numpy函数vectorize使用两列作为输入来调用函数。

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

答案 1 :(得分: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()快,但我不确定。