Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting diagonal elements of a numpy array

Tags:

python

numpy

Given input

A = np.array([[1,2,3],[4,5,6],[7,8,9]])
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

Need output :

array([[2, 3],
       [4, 6],
       [7, 8]])

It is easy to use iteration or loop to do this, but there should be a neat way to do this without using loops. Thanks

like image 711
Bill Ancalagon the black Avatar asked Oct 13 '17 18:10

Bill Ancalagon the black


People also ask

How do I remove part of a NumPy array?

To remove an element from a NumPy array: Specify the index of the element to remove. Call the numpy. delete() function on the array for the given index.

How do you extract the diagonal elements of a matrix in NumPy?

NumPy: diag() function The diag() function is used to extract a diagonal or construct a diagonal array. If v is a 2-D array, return a copy of its k-th diagonal. If v is a 1-D array, return a 2-D array with v on the k-th diagonal.

How do I clean my NumPy array?

Using the NumPy function np. delete() , you can delete any row and column from the NumPy array ndarray . Specify the axis (dimension) and position (row number, column number, etc.). It is also possible to select multiple rows and columns using a slice or a list.


Video Answer


2 Answers

Approach #1

One approach with masking -

A[~np.eye(A.shape[0],dtype=bool)].reshape(A.shape[0],-1)

Sample run -

In [395]: A
Out[395]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [396]: A[~np.eye(A.shape[0],dtype=bool)].reshape(A.shape[0],-1)
Out[396]: 
array([[2, 3],
       [4, 6],
       [7, 8]])

Approach #2

Using the regular pattern of non-diagonal elements that could be traced with broadcasted additions with range arrays -

m = A.shape[0]
idx = (np.arange(1,m+1) + (m+1)*np.arange(m-1)[:,None]).reshape(m,-1)
out = A.ravel()[idx]

Approach #3 (Strides Strikes!)

Abusing the regular pattern of non-diagonal elements from previous approach, we can introduce np.lib.stride_tricks.as_strided and some slicing help, like so -

m = A.shape[0]
strided = np.lib.stride_tricks.as_strided
s0,s1 = A.strides
out = strided(A.ravel()[1:], shape=(m-1,m), strides=(s0+s1,s1)).reshape(m,-1)

Runtime test

Approaches as funcs :

def skip_diag_masking(A):
    return A[~np.eye(A.shape[0],dtype=bool)].reshape(A.shape[0],-1)

def skip_diag_broadcasting(A):
    m = A.shape[0]
    idx = (np.arange(1,m+1) + (m+1)*np.arange(m-1)[:,None]).reshape(m,-1)
    return A.ravel()[idx]

def skip_diag_strided(A):
    m = A.shape[0]
    strided = np.lib.stride_tricks.as_strided
    s0,s1 = A.strides
    return strided(A.ravel()[1:], shape=(m-1,m), strides=(s0+s1,s1)).reshape(m,-1)

Timings -

In [528]: A = np.random.randint(11,99,(5000,5000))

In [529]: %timeit skip_diag_masking(A)
     ...: %timeit skip_diag_broadcasting(A)
     ...: %timeit skip_diag_strided(A)
     ...: 
10 loops, best of 3: 56.1 ms per loop
10 loops, best of 3: 82.1 ms per loop
10 loops, best of 3: 32.6 ms per loop
like image 64
Divakar Avatar answered Sep 20 '22 20:09

Divakar


Just with numpy, assuming a square matrix:

new_A = numpy.delete(A,range(0,A.shape[0]**2,(A.shape[0]+1))).reshape(A.shape[0],(A.shape[1]-1))

like image 34
Erik Garcia Avatar answered Sep 21 '22 20:09

Erik Garcia