涉及前一行数据的 Python 向量化运算

2024-01-03

我很好地掌握了如何利用 pandas 和 numpy 对整个数据列进行矢量化操作。然而,我遇到了一种我似乎无法矢量化的情况。当计算涉及利用前一行的值来计算当前行时,我必须退回到 for 循环。

是否可以对这种事情进行矢量化?这是我的意思的一个简单例子:

# Test set of 20 random integers
df = pd.DataFrame({'base': [15, 16, 2, 16, 14,
                            1, 18, 18, 4, 7,
                            4, 18, 19, 13, 16,
                            11, 1, 8, 1, 9]})


# Empty array to hold calculated values
calc_data = np.empty((20, 1))

period = 14

for idx, value in enumerate(df.base):

    # Seeding the first element of the calculated array
    if idx == 0:
        calc_data[idx] = 5

    else:
        calc_data[idx] = (calc_data[idx - 1] * (period - 1) + df.base.iloc[idx]) / period

# Adding the column to the dataframe
df['calculated'] = calc_data

print(df)

Output:

    base  calculated
0     15    5.000000
1     16    5.785714
2      2    5.515306
3     16    6.264213
4     14    6.816769
5      1    6.401286
6     18    7.229765
7     18    7.999068
8      4    7.713420
9      7    7.662461
10     4    7.400857
11    18    8.157939
12    19    8.932372
13    13    9.222916
14    16    9.706994
15    11    9.799351
16     1    9.170826
17     8    9.087196
18     1    8.509539
19     9    8.544572

一种矢量化方式(将“矢量化”视为“避免 Python 级循环”)是将其视为线性信号滤波器 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.lfilter.html:

import numpy as np
import pandas as pd
import scipy.signal

def via_lfilter(arr):
    period = 14
    y0 = 5.0  # initial value

    # calc_data[idx] = (calc_data[idx - 1] * (period - 1) + df.base.iloc[idx]) / period
    b = [1.0/period]  # coefficients of 'original' terms
    a = [1.0, -(period-1)/period]  # coefficients of 'computed' terms

    zi = scipy.signal.lfiltic(b, a, [y0], x=arr[1::-1])

    y = np.zeros_like(arr)
    y[0] = y0
    result = scipy.signal.lfilter(b, a, arr[1:], axis=0, zi=zi)
    y[1:] = result[0]

    return y

但在现实世界中,我只使用 numba,它的设计正是为了给我们带来矢量化的性能优势,而不会带来麻烦:

import numba

@numba.jit(nopython=True)
def via_numba(arr):
    calc_data = np.zeros_like(arr)
    period = 14
    calc_data[0] = 5.0  # initial value
    for idx in range(1, len(arr)):
        calc_data[idx] = (calc_data[idx - 1] * (period - 1) + arr[idx]) / period
    return calc_data

这些给了我:

In [238]: df["vect"] = via_lfilter(df.base.values.astype(float))
     ...: df["via_numba"] = via_numba(df.base.values.astype(float))
     ...: 
     ...: 

In [239]: df
Out[239]: 
    base  calculated      vect  via_numba
0     15    5.000000  5.000000   5.000000
1     16    5.785714  5.785714   5.785714
2      2    5.515306  5.515306   5.515306
3     16    6.264213  6.264213   6.264213
4     14    6.816769  6.816769   6.816769
5      1    6.401286  6.401286   6.401286
6     18    7.229765  7.229765   7.229765
7     18    7.999068  7.999068   7.999068
8      4    7.713420  7.713420   7.713420
9      7    7.662461  7.662461   7.662461
10     4    7.400857  7.400857   7.400857
11    18    8.157939  8.157939   8.157939
12    19    8.932372  8.932372   8.932372
13    13    9.222916  9.222916   9.222916
14    16    9.706994  9.706994   9.706994
15    11    9.799351  9.799351   9.799351
16     1    9.170826  9.170826   9.170826
17     8    9.087196  9.087196   9.087196
18     1    8.509539  8.509539   8.509539
19     9    8.544572  8.544572   8.544572

并且两者在较大的框架下表现得相当合理:

In [240]: df = pd.DataFrame({"base": np.random.uniform(1, 100, 10**6)})

In [241]: %timeit via_lfilter(df.base.values.astype(float))
11.4 ms ± 49.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [242]: %timeit via_numba(df.base.values.astype(float))
11 ms ± 342 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

涉及前一行数据的 Python 向量化运算 的相关文章

随机推荐

  • 按位 XOR(异或)是什么意思?

    我试图理解 C 或一般情况下的二元运算符 特别是 异或 http msdn microsoft com en us library zkacc7k1 aspx 例如 给定一个正整数数组 除了一个出现奇数次的数字外 所有数字都出现偶数次 在
  • nodejs socket.io 在函数循环内发出

    我想通过循环内的 socket io 发出 为此 我制作了一个运行良好的触发器 但在每个触发器中我调用 socket emit 并且只有第一个发出有效 这是服务器代码 var server require http createServer
  • 从动态 PHP 页面生成 HTML 静态页面 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个脚本来在运行时从动态内容生成静态 HTML 页面 我基本上想做的就是保存那些缓存那些ht
  • 用于提取 HTML 图像属性的正则表达式

    我需要一个正则表达式模式来提取图像标签的所有属性 众所周知 存在大量格式错误的 HTML 因此该模式必须涵盖这些可能性 我正在看这个解决方案https stackoverflow com questions 138313 how to ex
  • 用于乐观更新的操作存储是 Redux/Flux 中的一个好方法吗?

    我一直在 React Flux 应用程序中进行乐观更新 并看到了两件事 如果用户在存在某些未完成的操作时尝试关闭窗口 会发生什么情况 例如 在 Facebook 中 即使没有真正持久化 消息也会出现在墙上 这就是乐观更新的作用 对用户来说是
  • flag_shih_tzu 可以处理的最大标志数量是多少?

    我正在使用 flag shih tzu gem 我想知道它可以处理的最大标志数量是多少 或者它是否取决于 int 标志列中的长度 我需要它来处理 64 个标志 can it 我是 flag shih tzu 的维护者 最佳实践 出于性能原因
  • 我是否正确使用了 Automapper 2.0 的 Include 功能?

    要么我没有 要么它不起作用 我有一个 Source 类 我想将其映射到彼此继承的多个视图 基本上 基类是 Detail 子类是 Edit 或 Update 它们使用与 Detail 相同的所有数据 再加上几个其他字段来管理自己的列表或其他内
  • 如何更改 allauth 中的电子邮件验证链接

    我在 django 应用程序中使用 allauth 创建用户后 它会发送一封包含如下链接的电子邮件http localhost 8001 account confirm email asdfafsd 不过 我希望链接是http localh
  • 通过 AlamofireImage 下载 UIImage? [复制]

    这个问题在这里已经有答案了 我有一个 URL 想通过返回函数下载图像 但是我无法让它正常配合 这是我的函数 func getTabImage url URL gt UIImage Alamofire request url response
  • 为多个客户端运行 Magento - 单个安装与多个安装

    我希望为多个客户端设置 Magento 社区版 安装 并且已经研究了几天这个问题 我可以看到企业版中有我需要的东西 但令人惊讶的是我不愿意支付每年 12 000 美元的订阅费用 似乎有一些选项可供选择 但我担心我将从各种选项中获得的性能 选
  • 删除 TensorFlow 图中除少数节点之外的所有节点

    我的 TensorFlow 用例要求我为每个需要处理的实例构建一个新的计算图 这最终会增加内存需求 除了少数几个tf Variables这些是模型参数 我想删除所有其他节点 其他有类似问题的人也发现了tf reset default gra
  • 如何在 Windows 中使用正则表达式匹配行尾

    我在 Windows 中创建了一个 txt 文件 现在应该在 Linux 中进行编辑 我想用 grep 匹配行尾 假设我要在文件中找到的行的内容是 foo bar bar 然后我发出命令grep r bar 但没有产生任何输出 在 Wind
  • 多线程 COMObject 和 UI 线程 (C#)

    这是我在这里发表的第一篇文章 因为实际上我通常用很棒的方法解决我所有的问题 您可以在这里找到邮政数据库 但我现在实际上陷入困境 我正在开发一个遵循 MVVM 的项目 其中包括一个 COM 对象 正如我在研究过程中所读到的那样 我了解到 CO
  • 具有多个代理的 Ember CLI

    问题 我有一个 Ember CLI 应用程序 它将使用多个 API 我需要在开发模式下代理这些 API 背景 我有一个遗留的 api 它在以下位置公开服务 api在我的本地开发机器上运行localhost 3000 我有一个新的 api 它
  • 申请家庭内如何分配?

    我有包含多个因素的 data frame 我想重命名所有这些因素的因素级别 例如 mydf lt data frame col1 as factor c A A NA NA col2 as factor c A NA NA A mydf l
  • 不同 Modelica 仿真环境之间有什么区别?

    有不同的 Modelica 仿真环境 包括 Dymola Wolfram SystemModeler OpenModelica 和 Jmodelica 所以 我尝试加载热流体库 ThermoSysProhttps github com Dw
  • 为什么命名元组使用的内存比字典少?

    我问这个是因为我觉得这很令人惊讶 我想namedtuple会有更多的开销 背景是我在内存中缓存了一个大型 Django 查询 发现 Django 对象的大小是 values 然后我想知道什么开销namedtuple对象的版本将是 允许我仍然
  • 从一个 SQS 触发器触发多个 lambda 函数

    我不确定我是否正确理解 AWS Lambda SQS 触发器 我是否可以将其配置为一个 SQS 队列可以根据消息正文或消息属性触发不同的 lambda 函数 我的用例 我有三个不同的 lambda 函数 processCricket pro
  • java.lang.RuntimeException:运行命令获取文件权限时出错:ExitCodeException exitCode=-1073741515

    问题的标题是我在 Windows 10 上安装 Hadoop 2 9 1 时遇到的异常 经过几周的研究 我无法找到我的标题查询的答案 根据我收到的异常 hadoop 进程正在数据目录中查找权限 但我已经在管理员模式下运行 dfs cmd 和
  • 涉及前一行数据的 Python 向量化运算

    我很好地掌握了如何利用 pandas 和 numpy 对整个数据列进行矢量化操作 然而 我遇到了一种我似乎无法矢量化的情况 当计算涉及利用前一行的值来计算当前行时 我必须退回到 for 循环 是否可以对这种事情进行矢量化 这是我的意思的一个