【问题标题】:How to speed up Numpy array slicing within a for loop? [duplicate]如何在 for 循环中加速 Numpy 数组切片? [复制]
【发布时间】:2021-08-06 17:02:53
【问题描述】:

我有一个原始数组,例如:

import numpy as np
original = np.array([56, 30, 48, 47, 39, 38, 44, 18, 64, 56, 34, 53, 74, 17, 72, 13, 30, 17, 53])

所需的输出是一个由固定大小的窗口组成的数组,该窗口通过多次迭代滑动,类似于

[56, 30, 48, 47, 39, 38],
[30, 48, 47, 39, 38, 44],
[48, 47, 39, 38, 44, 18],
[47, 39, 38, 44, 18, 64],
[39, 38, 44, 18, 64, 56],
[38, 44, 18, 64, 56, 34],
[44, 18, 64, 56, 34, 53],
[18, 64, 56, 34, 53, 74],
[64, 56, 34, 53, 74, 17],
[56, 34, 53, 74, 17, 72]

目前我正在使用

def myfunc():
    return np.array([original[i: i+k] for i in range(i_range)])

使用参数i_range = 10k = 6,使用python 的timeit 模块(10000 iter),我接近0.1 秒。这有可能提高 100 倍吗?

我也尝试过 Numba,但结果并不理想,因为它在使用更大的阵列时效果更好。

注意:本文中使用的数组为演示目的而减少,original 的实际大小约为 500。

【问题讨论】:

标签: python arrays numpy


【解决方案1】:

【讨论】:

  • 引用这个新函数很好,但你应该详细说明它是如何应用于这个案例的。
  • 文档中的示例与作者想要的几乎相同
【解决方案2】:

正如 RandomGuy 所建议的,您可以使用 stride_tricks:

np.lib.stride_tricks.as_strided(original,(i_range,k),(8,8))

对于较大的数组(以及i_rangek),这可能是最有效的,因为它不分配任何额外的内存,有一个缺点 - 编辑创建的数组也会修改原始数组,除非你复印。 (8,8) 参数定义了内存中每个方向前进多少字节,我使用 8 作为其原始数组步长。

另一个选项,更适合较小的数组:

def myfunc2():
    i_s = np.arange(i_range).reshape(-1,1)+np.arange(k)
    return original[i_s]

这比您的原始版本更快。 然而,两者都不是快 100 倍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多