卷积函数(内核)而不是乘法?

时间:2016-01-11 22:46:09

标签: python numpy scipy convolution

numpy.convolve(数据,内核)确实卷入。

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

这是函数(欧几里德距离): 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

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

1 个答案:

答案 0 :(得分: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