python - 如何加快涉及 Pandas 前一行的计算?

标签 python pandas dataframe numba

我正在尝试使用自己创建的列的移位值创建一个新的 Pandas DataFrame 列。

我能够做到这一点的唯一方法是遍历数据,这太慢了,会导致我的代码出现瓶颈。

import pandas as pd 

df = pd.DataFrame([1,6,2,8], columns=['a'])
df.at[0, 'b'] = 5

for i in range(1, len(df)):
    df.loc[i, ('b')] = (df.a[i-1] + df.b[i-1]) /2

我尝试使用 shift,但没有成功。它为第 1 行填充值,其余为 NaN。我假设此方法无法即时读取新创建的值。

df.loc[1:, ('b')] = (df.a.shift() + df.b.shift()) /2

更新

通过在迭代中使用 df.at 而不是 df.loc,我能够显着减少时间

def with_df_loc(df):
    for i in range(1, len(df)):
        df.loc[i, ('b')] = (df.a[i-1] + df.b[i-1]) /2
    return df

def with_df_at(df):
    for i in range(1, len(df)):
        df.at[i, 'b'] = (df.a[i-1] + df.b[i-1]) /2
    return df



%timeit with_df_loc(df)
183 ms ± 75.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit with_df_at(df)
19.4 ms ± 2.74 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

此计时基于 150 行的较大数据集。考虑到 df.rolling(20).mean() 大约需要 3 毫秒,我认为这可能是我能做的最好的了。

感谢您的回答,如果我需要进一步优化,我会查看 Asish M numba 的建议。

最佳答案

我们可以使用numba要加快计算速度,请参阅 Enhancing performance文档中的部分。

import numba 

@numba.njit
def func(a, b_0=5):
    n = len(a)
    b = np.full(n, b_0, dtype=np.float64)
    for i in range(1, n):
        b[i] = (b[i - 1] + a[i - 1]) / 2
    return b

df['b'] = func(df['a'].to_numpy())
df

   a     b
0  1  5.00
1  6  3.00
2  2  4.50
3  8  3.25

比较性能

Benchmarking code, for reference .

enter image description here

蓝线代表您当前方法的最快版本的性能(使用 .at)。橙色线代表 numba 的性能。

关于python - 如何加快涉及 Pandas 前一行的计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65454878/

相关文章:

python - 有没有更好的方法将文字与背景分开?

java - Java中的@override和Python中的@decorator的区别

python - 使用 south 重构具有继承的 Django 模型

python - 终止使用 python 子进程 Popen 启动的进程时如何关闭标准输出管道?

python - 将列值添加到后续行,直到出现新的列值

python - Pandas:在 500 万行上使用 Apply 和正则表达式字符串匹配

python - Pandas :如果关键字出现在任何列中,则选择行

python - 无法制作所需的 pandas 数据框

r - 在 R 函数中存储数据

r - 收到错误 "number of items to replace is not a multiple of replacement length"