Search code examples
pythonnumpysparse-matrix

Seamlessly and efficiently flipping numpy array or sparse matrix along all axes


Let's say we have a matrix (numpy array) of unknown shape, the shape can be for example (1,5) (row), (5,1) (column), (5,5) (square), (5,6) (non-square) or (5,) (degenerated) (ok the last case isn't a matrix but is a valid input).

I would like to given a matrix of any shape (column, row, square, nonsquare, degenerated). I will return a flipped up/down left/right version of it.

Since np.flip has some issues with 1d arrays. My approach was:

def flipit(M):
    return M.ravel()[::-1].reshape(M.shape)

It works, but is that acceptable? Any faster ways to do it?

In the other hand, how can I do the same for sparse matrices (for example if M is scipy.sparse.csr_matrix).


Solution

  • We can use slice notation with a step-size of -1 for the number of dims in the input to flip along all the axes, as that's what the original code is essentially doing. This would cover both arrays and sparse matrices -

    def flip_allaxes(a): # a can be array or sparse matrix
        # generate flipping slice
        sl = slice(None,None,-1) # or np.s_[::-1] suggested by @kmario23
        return a[tuple([sl]*a.ndim)]
    

    Simplified on newer NumPy versions (15.1 onwards)

    On newer NumPy versions : Version 15.1 and newer, that allows us to specify tuple of ints for the axes along which the flipping is needed. For the default case with axis=None from the docs, it flips along all axes. Thus, to solve our case, it would be simply np.flip(a) and this would again cover both generic ndarrays and sparse matrices.