【问题标题】:Separable filter on numpy arraynumpy数组上的可分离过滤器
【发布时间】:2015-04-24 23:45:17
【问题描述】:

假设我有一个 numpy 数组 a,我想创建一个新数组 b 这样 b[i, j] 是一个函数,比如说:

a[i-1, j-1], a[i-1, j  ], a[i-1, j+1],
a[i  , j-1], a[i  , j  ], a[i  , j+1],
a[i+1, j-1], a[i+1, j  ], a[i+1, j+1]

最快的方法是什么?

由于这是一个可分离的过滤器,有没有办法在多个线程中运行它? (不是进程,因为我必须将数据复制回来)

还是必须编写 C 代码来绕过 GIL?

也欢迎部分解决方案(例如假设函数是线性的)。

【问题讨论】:

  • 您的意思是像滚动/移动窗口还是过滤器?此链接中的示例用于对 2D 数组 johnvinyard.com/blog/?p=268 上的 3x3 窗口求和
  • 听起来像许多其他 SO 问题,大多数使用术语 sliding windows(或移动)。尽管大多数人专注于迭代窗口,而不是在线程或进程之间拆分任务。

标签: python arrays image-processing numpy gil


【解决方案1】:

像这样使用滑动窗口的理想化numpy 方法是构造一个 4D 数组

C.shape = (N,M,3,3)

在哪里

C[i,j,:,:] = np.array([a[i-1, j-1], a[i-1, j  ], a[i-1, j+1],
                       a[i  , j-1], a[i  , j  ], a[i  , j+1],
                       a[i+1, j-1], a[i+1, j  ], a[i+1, j+1]])

并编写您的函数对最后 2 个维度进行某种缩减。 summean 是典型的,例如

B = C.sum(axis=(2,3))

其他 SO 问题展示了如何使用 np.lib.stride_tricks.as_strided 构造这样的数组。但是只有一个 3x3 的子数组,做类似的事情可能同样快

C = np.zeros((N,M,3,3))
C[:,:,0,0] = a[:-1,:-1]
etc.

(或者使用hstackvstack达到同样的效果)。

但是跨步方法的一个好处(或者可能不是那么好)是它不涉及复制a 的任何数据 - 它只是一个视图。

至于将工作分成几部分,我可以想象使用C 的切片(在第一个二维上),例如

 C[0:100,0:100,:,:].sum(axis=(2,3))

【讨论】:

    猜你喜欢
    • 2021-07-05
    • 2019-01-31
    • 2019-07-07
    • 2020-02-13
    • 1970-01-01
    • 2018-06-06
    • 2017-09-29
    • 1970-01-01
    相关资源
    最近更新 更多