简体   繁体   中英

Numpy Array Reversing Diagonal

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]

Benchmarking

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM