【问题标题】:Fastest way to shift a Numpy array移动 Numpy 数组的最快方法
【发布时间】:2015-07-27 13:39:21
【问题描述】:

我正在运行一些模拟,这些模拟涉及反复比较 2D Numpy 数组中的值与其“邻居”;例如。索引位置(y,x) 的值与同一数组中索引位置(y-1,x) 的值进行比较。

目前我正在使用这样的功能:

# example of the typical size of the arrays
my_array = np.ndarray((500,500))    

shapey, shapex = my_array.shape
Yshape = (1, shapex)
Yzeros = np.zeros((1, shapex))

def syf(A, E=True):
    if E == True:
        return np.concatenate((A[1:], A[-1].reshape(Yshape)), axis=0)
    else:
        return np.concatenate((A[1:], Yzeros), axis=0)

shifted_array = syf(my_array)

difference_in_y = shifted_array - my_array 

这可以选择使用边缘值或零在数组边缘进行比较。这些函数也可以在任一轴的任一方向上执行此操作。

有人对更快的方法有什么建议吗? 我试过np.roll(慢得多),这个:

yf = np.ix_(range(shapey)[1:] + [shapey,], range(shapex))
shifted_array = my_array[yf]

这有点慢。

在需要 10 小时运行的程序中,这些函数每秒调用约 200 次,因此任何小的加速都更受欢迎!

谢谢。

编辑:

因此,如果每次调用移位函数时都需要相同的微分方法,那么下面的 Divakars 方法似乎提供了一个小的加速,但是如果只需要一个移位数组,那么该方法和我上面使用的方法似乎是相等的速度。

【问题讨论】:

  • 我本来建议使用scipy.ndimage.convolve1d,但对于这种情况(非常短的过滤器),它实际上比您当前的方法慢约 2 倍。
  • 查看roll的代码,它会生成一个类似yf的索引,然后使用take
  • 鉴于新数组与旧数组几乎相同,我很惊讶没有更快的方法通过索引来避免在内存中创建新数组。虽然我猜如果roll 使用np.ix_ 索引,那么可能没有更快的替代方案

标签: python arrays performance numpy


【解决方案1】:

您可以像这样在函数调用中完成移位和微分 -

def syf1(A, E=True):
    out = np.empty_like(A)
    out[:-1] = A[1:] - A[:-1] # Or np.diff(my_array,axis=0)
    if E == True:
        out[-1] = 0
    else:
        out[-1] = -A[-1]
    return out

因此,用于运行时比较的 syf 的等效修改版本将是 -

def syf(A, E=True):
    if E == True:
        return np.concatenate((A[1:], A[-1].reshape(Yshape)), axis=0) - A
    else:
        return np.concatenate((A[1:], Yzeros), axis=0) - A

运行时测试

让我们将 syf 的等效版本与问题代码中列出的输入的运行时性能建议方法进行比较 -

In [113]: %timeit syf(my_array)
1000 loops, best of 3: 518 µs per loop

In [114]: %timeit syf1(my_array)
1000 loops, best of 3: 494 µs per loop

所以,那里有一些的改进!

【讨论】:

  • 别忘了你也可以if E:!!
  • @Matthew 感谢您的提示。我会暂时保留它,因为它确实是一件小事,直到 OP 回来提供任何反馈。尽管如此,还是很感激这个提示!
  • 感谢 Divakar 的建议,我尝试了一个稍微不同的实现(我的代码并不总是以这种方式区分,所以只使用了'shift'),这两种方法在速度上基本相同......奇怪的是它们如此相似,我想这只是内存访问时间。
  • @Siyh 换档或换档+差异或其他方式的不同方式?
  • 有时与上面的区别,但也是 > 或
猜你喜欢
  • 2011-01-23
  • 2021-11-11
  • 2022-01-09
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多