Correlation of 2 time dependent multidimensional signals (signal vectors)

前端 未结 3 1137
有刺的猬
有刺的猬 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:05

    I think it's this: (please correct if wrong!)

    import numpy as np
    
    M1 = np.array ([
        [1, 2, 3, 4],
        [2, 3, 1, 4.5]
    ])
    
    M2 = np.array ([
        [10, 20, 33, 40],
        [20, 35, 15, 40]
    ])
    
    v = np.diagonal (np.corrcoef (M1, M2), M1.shape [0])
    
    print (v)
    

    Which prints:

    [ 0.99411402  0.96131896]
    

    Since it's got only one dimension, I can think of it as a column-vector...

    0 讨论(0)
  • 2020-11-29 14:10

    not knowing enough of numpy array magic, I'd just pick out the rows, feed each pair individually to corrcoeff

    [np.corrcoef(i,j)[0][1] for i,j in zip(a,b)]
    

    for a np.array column output

    c, c.shape = np.array([np.corrcoef(i,j)[0][1] for i,j in zip(a,b)]), (a.shape[0], 1)
    

    I'm sure there's better using numpy broadcast/indexing features

    0 讨论(0)
  • 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!

    0 讨论(0)
提交回复
热议问题