I have a covariance matrix $\Sigma$ that corresponds to measurements taken at times $t$. So $\Sigma_{ij}$ is the covariance between the measurement taken at time $t_i$ and $t_j$. The trouble is that $t$ is that is unsorted. I need to use $\Sigma$ but where it's entries are sorted with time. How would I sort the entries of $\Sigma$ with increasing time using NumPy?
import numpy as np
# Make random values in the shape of a covariance matrix (the values aren't important for this problem)
covmat = np.random.randn(10, 10)
times = np.random.randn(10,1).squeeze()
indices = np.argsort(times)
# Now what do I do with these indices?
Here's a working example done with loops. I think there is probably a more elegent solution:
import numpy as np
A = np.array([[1, 2, 4, 6, 9],
[2, 3, 5, 8, 11],
[4, 5, 7, 10, 13],
[6, 8, 10, 12, 14],
[9, 11, 13, 14, 15]])
sort_indices = [2, 3, 4, 1, 0]
sorted_A = np.zeros_like(A)
for i in range(A.shape[0]):
for j in range(A.shape[1]):
sorted_A[i,j] = A[sort_indices[i], sort_indices[j]]
print(sorted_A)
>[[ 7 10 13 5 4]
[10 12 14 8 6]
[13 14 15 11 9]
[ 5 8 11 3 2]
[ 4 6 9 2 1]]
The covariance matrix has by definition the entries $\Sigma_{ij} = \operatorname{cov}(x(t_i), x(t_j))$ now, you are interested in the covariance matrix of the reordered time series $\tilde t_k = t_{\pi(k)}$, where $\pi$ is a given permutation (e.g. the permutation that *un*sorts the time series). Then correspondingly, $$ \tilde \Sigma_{ij} = \operatorname{cov}(x(t_{\pi(i)}), x(t_{\pi(j)})) = \Sigma_{\pi(i), \pi(j)}$$
You have 2 options: to permute the rows/columns of a matrix, you can multiply by permutation matrices from the left/right: $$\tilde \Sigma = P^T \Sigma P \iff \Sigma = P\tilde \Sigma P^T$$
where $P$ is the permutation matrix induced by $\pi$. Alternatively, you can use the indices obtained by the
p = np.argsort(p)directly to avoid having to do the actual matrix multiplication via indexingS[p][:,p]short demo: