The following piece of code averages the ante-diagonal elements of a 2d array
x of size (m,n) with, for my purpose, m > n.
import numpy as np def average_adiag(x): """Average antidiagonal elements of a 2d array Parameters: ----------- x : np.array 2d numpy array of size Return: ------- x1d : np.array 1d numpy array representing averaged antediangonal elements of x """ x1d = [np.mean(x[::-1, :].diagonal(i)) for i in range(-x.shape + 1, x.shape)] return np.array(x1d)
x = np.arange(12).reshape(4,3) print(average_adiag(x))
[ 0. 2. 4. 7. 9. 11.]
I make an intensive use of this function in my code and it has been profiled as a performance bottleneck. The code was inspired from this answer. I haven't found any better way on my own. Any performance improvement would be appreciated.
This code is associated with the Singular Spectrum Analysis algorithm for time series decomposition. Basically, I use time series of length 20k that are turned into a trajectory matrix of shape (10k,10k). The latter is decomposed using singular value decomposition in to 10k components. For a given number
n of first singular components (usually 50), I reconstruct
n 2d array and average their anti-diagonals elements to have back
n time series. These are appreciated with a graphical plot of a correlation matrix.
I will not speed up the SVD algorithm, but SVD results are saved. The anti-diagonal averaging is used for exploration of the results but it is slow. Usually, the function
n (50 by default) times on matrix of size (10k, 10k). It takes a bit more than 1 minutes on my PC. It seems slow to me, especially for generating a plot, and this is why I want to improve it if possible.