如何用pandas-python递归地构造一列数据帧?

use*_*223 6 python recursion multiple-columns dataframe pandas

给出这样一个数据框df:

id_      val     
11111    12
12003    22
88763    19
43721    77
...
Run Code Online (Sandbox Code Playgroud)

我想添加一列diffdf,并且它的每一行等于,我们说了,val在该行减去diff上一行和乘0.4,然后加入diff前一天:

diff = (val - diff_previousDay) * 0.4 + diff_previousDay
Run Code Online (Sandbox Code Playgroud)

并且diff第一行中的等于val * 4该行.也就是说,预期df应该是:

id_      val     diff   
11111    12      4.8
12003    22      11.68
88763    19      14.608
43721    77      ...
Run Code Online (Sandbox Code Playgroud)

我试过了:

mul = 0.4
df['diff'] = df.apply(lambda row: (row['val'] - df.loc[row.name, 'diff']) * mul + df.loc[row.name, 'diff'] if int(row.name) > 0 else row['val'] * mul, axis=1) 
Run Code Online (Sandbox Code Playgroud)

但得到如错误:

TypeError :("不支持的操作数类型 - :'float'和'NoneType'",'发生在索引1')

你知道如何解决这个问题吗?先感谢您!

jez*_*ael 7

您可以使用:

df.loc[0, 'diff'] = df.loc[0, 'val'] * 0.4

for i in range(1, len(df)):
    df.loc[i, 'diff'] = (df.loc[i, 'val'] - df.loc[i-1, 'diff']) * 0.4  + df.loc[i-1, 'diff']

print (df)
     id_  val     diff
0  11111   12   4.8000
1  12003   22  11.6800
2  88763   19  14.6080
3  43721   77  39.5648
Run Code Online (Sandbox Code Playgroud)

输入依赖于先前步骤的结果的计算的迭代性质使矢量化复杂化。您也许可以将 apply 与执行与循环相同的计算的函数一起使用,但在幕后这也将是一个循环。

  • 对不起@user5779223,但它并不快!我有一个 1,7 M 行 x 11 列的数据集,我需要在具有大约 80k 个不同值的列上“分组”,并“应用”这种运行聚合(里面有一点“if”)。`cumsum` 和 `cumcount` 分别运行 800 和 300 微秒。应用的回调,在 `GroupByDataframe` 上执行 `iterrows` 运行 4 分钟。我目前正在检查 `numba` 是否可以帮助我。 (2认同)

jpp*_*jpp 5

递归函数不容易矢量化。但是,您可以使用numba. 这应该比常规循环更可取。

from numba import jit

@jit(nopython=True)
def foo(val):
    diff = np.zeros(val.shape)
    diff[0] = val[0] * 0.4
    for i in range(1, diff.shape[0]):
        diff[i] = (val[i] - diff[i-1]) * 0.4 + diff[i-1]
    return diff

df['diff'] = foo(df['val'].values)

print(df)

     id_  val     diff
0  11111   12   4.8000
1  12003   22  11.6800
2  88763   19  14.6080
3  43721   77  39.5648
Run Code Online (Sandbox Code Playgroud)