Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:有效地计算Cadzow过滤器的非对角元素的平均值_Python_Performance_Filter_Data Processing - Fatal编程技术网

Python:有效地计算Cadzow过滤器的非对角元素的平均值

Python:有效地计算Cadzow过滤器的非对角元素的平均值,python,performance,filter,data-processing,Python,Performance,Filter,Data Processing,我目前正在用Python实现Gadzow过滤器 放在某个上下文中。从一维数组开始(以range(10)为例),然后用它构建一个类似Hankel的矩阵 H= [[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8], [4, 5, 6, 7, 8, 9]]) 然后用这个矩阵做一些线性代数,这是没有问题的。之后,最耗时的步骤是平均问题 在一个新矩阵B中,求出结果矩阵

我目前正在用Python实现Gadzow过滤器

放在某个上下文中。从一维数组开始(以range(10)为例),然后用它构建一个类似Hankel的矩阵

H= [[0, 1, 2, 3, 4, 5],
    [1, 2, 3, 4, 5, 6],
    [2, 3, 4, 5, 6, 7],
    [3, 4, 5, 6, 7, 8],
    [4, 5, 6, 7, 8, 9]])
然后用这个矩阵做一些线性代数,这是没有问题的。之后,最耗时的步骤是平均问题

在一个新矩阵B中,求出结果矩阵元素的平均值。在第一行中,通过路径对所有元素求平均值,该路径由H中的精度给出。因此类似于非对角线,但从右上角到左下角。在第二个切片中,忽略第一行,依此类推

矩阵$H$在此分析步骤下是不变的,但例如矩阵

1 2 2 1
1 1 1 1
1 1 1 1
将成为

1 1.5 1.33 1
1 1   1    1
1 1   1    1
好吧,我希望你能理解这个问题。我的(工作但效率低下)代码是

对于包含2048个数据点的数据,这需要一段时间,从而生成1024x1023矩阵

我很高兴能有一些技巧来加速这一进程


谢谢

您可以将输入矩阵与过滤器矩阵进行卷积,以加快代码的速度。可以定义滤波器矩阵,以便在卷积的每个步骤中,仅提取给定坐标处的反对角线。基本上,你的滤波器矩阵只是一个反单位矩阵。最后,由于卷积只对反对角线的元素求和,因此必须将输出除以正确的样本数,以获得平均值:

import numpy as np
from scipy.signal import fftconvolve
from time import time


def av_diag(A,i,j):
    dim = A.shape
    lim = min((dim[0]-i,j+1))
    return np.mean([A[i+it,j-it] for it in range(lim)])

def avHankel(A):
    return np.array([[av_diag(A,i,j) for j in range(len(A[0]))] for i in range(len(A))])


def fast_avHankel(A):
    m, n = A.shape
    filt = np.eye(m)[:,::-1]
    Apad = np.pad(A, ((0, m-1), (m-1, 0)), mode = "constant", constant_values = 0)
    Asum = fftconvolve(Apad, filt, mode = "valid")
    Adiv = np.array([ [ min(m-i, j+1) for j in range(n) ] for i in range(m) ])
    return Asum / Adiv


if __name__ == "__main__":
    A = np.random.rand(500, 500)

    starttime = time()
    Hold = avHankel(A)
    print(time() - starttime)    # 10.6 seconds on a laptop

    starttime = time()
    Hnew = fast_avHankel(A)
    print(time() - starttime)    # 0.26 seconds on a laptop

这看起来很棒,我不得不考虑一下,你在做什么,但是非常感谢
import numpy as np
from scipy.signal import fftconvolve
from time import time


def av_diag(A,i,j):
    dim = A.shape
    lim = min((dim[0]-i,j+1))
    return np.mean([A[i+it,j-it] for it in range(lim)])

def avHankel(A):
    return np.array([[av_diag(A,i,j) for j in range(len(A[0]))] for i in range(len(A))])


def fast_avHankel(A):
    m, n = A.shape
    filt = np.eye(m)[:,::-1]
    Apad = np.pad(A, ((0, m-1), (m-1, 0)), mode = "constant", constant_values = 0)
    Asum = fftconvolve(Apad, filt, mode = "valid")
    Adiv = np.array([ [ min(m-i, j+1) for j in range(n) ] for i in range(m) ])
    return Asum / Adiv


if __name__ == "__main__":
    A = np.random.rand(500, 500)

    starttime = time()
    Hold = avHankel(A)
    print(time() - starttime)    # 10.6 seconds on a laptop

    starttime = time()
    Hnew = fast_avHankel(A)
    print(time() - starttime)    # 0.26 seconds on a laptop