【问题标题】:Convolve a function(kernel) instead of multiplication?卷积函数(内核)而不是乘法?
【发布时间】:2016-01-12 20:12:53
【问题描述】:

numpy.convolve(data,kernel) 确实卷积。

我想要的是卷积内核和滑动数据的函数而不是将它们相乘,我该怎么做?

这是函数(欧几里得距离): numpy.linalg.norm(kernel - data_frame)

谢谢


类似:

np.linalg.norm( (rolling_window(array([1,1,0,0,1,0,1]),2) * [0.6,0.2]) - [0,1] , axis=1 )

http://www.rigtorp.se/2011/01/01/rolling-statistics-numpy.html

这是一个解决方案,但我怀疑它可能会更好!可能是!!

【问题讨论】:

  • 你的内核是一个 n 维向量并且你的数组是由向量组成的吗?然后类似卷积的操作可能不是您所需要的。你能把这描述得更详细一点吗?
  • 数据和内核的一维数组。
  • 卷积是缩放和求和。在您的情况下,缩放、减法、平方和求和的操作要复杂得多。如果不存在减法并且窗口只有 2 个元素,我们可以考虑在那里使用卷积。

标签: python numpy scipy convolution


【解决方案1】:

这是一个更复杂但更快的解决方案:

用convolve()表达你的函数,你的函数是:

sqrt(sum((x[t + i] * k[i] - v[i])**2, i=0..N-1))

sum() 部分可以扩展为:

convolve(x**2, k[::-1]**2) + convolve(x, (-2*k*v)[::-1]) + sum(v**2)

代码如下:

import numpy as np

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

def rolling_norm1(arr, k, v):
    return np.linalg.norm( (rolling_window(arr, len(k)) * k) - v, axis=1)

def rolling_norm2(arr, k, v):
    k = k[::-1]
    v = v[::-1]
    arr2 = arr ** 2
    k2 = k ** 2
    k1 = -2 * k * v
    c = np.sum(v**2)
    tmp = np.convolve(arr2, k2, mode="valid")
    tmp += np.convolve(arr, k1, mode="valid")
    tmp += c
    np.sqrt(tmp, out=tmp)
    return tmp

结果是一样的:

a = np.random.rand(1000)
k = np.random.rand(2)
v = np.random.rand(2)

np.allclose(rolling_norm1(a, k, v), rolling_norm2(a, k, v))

输出:

True

但 rolling_norm2() 快 2 倍:

%timeit rolling_norm1(a, k, v)
10000 loops, best of 3: 76.6 µs per loop

%timeit rolling_norm2(a, k, v)
10000 loops, best of 3: 31 µs per loop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    • 2022-01-15
    • 2021-02-06
    • 2020-10-10
    • 2018-10-28
    • 2011-10-23
    • 2021-01-03
    相关资源
    最近更新 更多