Is there an easy way in numpy to reverse the order of the diagonal of a matrix? I have a 2x2 matrix like this:
[ 213 5
198 24 ]
but I want it to be like this:
[ 24 5
198 213 ]
I've played around with np.diagonal
, but not sure how I can do this efficiently without a loop.
For 2x2
matrix:
a[::-1].T[::-1]
For a general nxn
:
idx = np.arange(len(a))
a[idx,idx] = np.diagonal(a)[::-1]
Here's one with np.einsum
-
def flip_diag(a):
w = np.einsum('ii->i',a)
w[:] = w[::-1]
return a
Another with np.fill_diagonal
-
np.fill_diagonal(a,np.diag(a)[::-1].copy())
Another with flattend indexing -
a.flat[::a.shape[1]+1] = a.flat[::-a.shape[1]-1]
Solutions as functions:
# @Quang Hoang's soln
def range_diagonal(a):
idx = np.arange(len(a))
a[idx,idx] = np.diagonal(a)[::-1]
return a
def fill_diagonal(a):
np.fill_diagonal(a,np.diag(a)[::-1].copy())
return a
def flattened_index(a):
a.flat[::a.shape[1]+1] = a.flat[::-a.shape[1]-1]
return a
Using benchit
package (few benchmarking tools packaged together; disclaimer: I am its author) to benchmark proposed solutions.
import benchit
funcs = [range_diagonal, flip_diag, fill_diagonal, flattened_index]
in_ = [np.random.rand(n,n) for n in [2,5,8,20,50,80,200,500,800,2000,5000]]
t = benchit.timings(funcs, in_)
t.plot(logx=True, save='timings.png')
flip_diag
and flattened_index
look good and choosing one among them could be based on the input array sizes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.