Correlation of 2 time dependent multidimensional signals (signal vectors)

前端 未结 3 1156
有刺的猬
有刺的猬 2020-11-29 13:29

I have a matrix M1 , each row of which is a time-dependent signal.

And I have another matrix, M2, of the same dimensions, each row of which is also a time dependent

3条回答
  •  鱼传尺愫
    2020-11-29 14:25

    Based on this solution to finding correlation matrix between two 2D arrays, we can have a similar one for finding correlation vector that computes correlation between corresponding rows in the two arrays. The implementation would look something like this -

    def corr2_coeff_rowwise(A,B):
        # Rowwise mean of input arrays & subtract from input arrays themeselves
        A_mA = A - A.mean(1)[:,None]
        B_mB = B - B.mean(1)[:,None]
    
        # Sum of squares across rows
        ssA = (A_mA**2).sum(1);
        ssB = (B_mB**2).sum(1);
    
        # Finally get corr coeff
        return np.einsum('ij,ij->i',A_mA,B_mB)/np.sqrt(ssA*ssB)
    

    We can further optimize the part to get ssA and ssB by introducing einsum magic there too!

    def corr2_coeff_rowwise2(A,B):
        A_mA = A - A.mean(1)[:,None]
        B_mB = B - B.mean(1)[:,None]
        ssA = np.einsum('ij,ij->i',A_mA,A_mA)
        ssB = np.einsum('ij,ij->i',B_mB,B_mB)
        return np.einsum('ij,ij->i',A_mA,B_mB)/np.sqrt(ssA*ssB)
    

    Sample run -

    In [164]: M1 = np.array ([
         ...:     [1, 2, 3, 4],
         ...:     [2, 3, 1, 4.5]
         ...: ])
         ...: 
         ...: M2 = np.array ([
         ...:     [10, 20, 33, 40],
         ...:     [20, 35, 15, 40]
         ...: ])
         ...: 
    
    In [165]: corr2_coeff_rowwise(M1, M2)
    Out[165]: array([ 0.99411402,  0.96131896])
    
    In [166]: corr2_coeff_rowwise2(M1, M2)
    Out[166]: array([ 0.99411402,  0.96131896])
    

    Runtime test -

    In [97]: M1 = np.random.rand(256,200)
        ...: M2 = np.random.rand(256,200)
        ...: 
    
    In [98]: out1 = np.diagonal (np.corrcoef (M1, M2), M1.shape [0])
        ...: out2 = corr2_coeff_rowwise(M1, M2)
        ...: out3 = corr2_coeff_rowwise2(M1, M2)
        ...: 
    
    In [99]: np.allclose(out1, out2)
    Out[99]: True
    
    In [100]: np.allclose(out1, out3)
    Out[100]: True
    
    In [101]: %timeit np.diagonal (np.corrcoef (M1, M2), M1.shape [0])
         ...: %timeit corr2_coeff_rowwise(M1, M2)
         ...: %timeit corr2_coeff_rowwise2(M1, M2)
         ...: 
    100 loops, best of 3: 9.5 ms per loop
    1000 loops, best of 3: 554 µs per loop
    1000 loops, best of 3: 430 µs per loop
    

    20x+ speedup there with einsum over the built-in np.corrcoef!

提交回复
热议问题