Home > database >  How to get reverse diagonal from a certain point in a 2d numpy array
How to get reverse diagonal from a certain point in a 2d numpy array

Time:03-18

Let's say I have a n x m numpy array. For example:

array([[ 1,  2,  3,  4,  5],
    [ 6,  7,  8,  9, 10],
    [11, 12, 13, 14, 15],
    [16, 17, 18, 19, 20]])

Now I want both diagonals intersection with a certain point (for example (1,2) which is 8). I already know that I can get the diagonal from top to bottom like so:

row = 1
col = 2
a = np.array(
    [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]
)
diagonal_1 = a.diagonal(col - row)

Where the result of col - row gives the offset for the diagonal.

Now I want to also have the reverse diagonal (from bottom to top) intersecting with the first diagonal in a random point (in this case (1,2), but it can be any point). But for this example it would be:

[16, 12, 8, 4]

I already tried a bunch with rotating and flipping the matrix. But I can't get a hold on the offset which I should use after rotating or flipping the matrix.

CodePudding user response:

You can use np.eye to create a diagnal line of 1's, and use that as a mask:

x, y = np.nonzero(a == 8)

k = y[0] - a.shape[0]   x[0]   1
nums = a[np.eye(*a.shape, k=k)[::-1].astype(bool)][::-1]

Output:

>>> nums
array([16, 12,  8,  4])

If you need to move the position of the line, increment/decrement the k parameter passed to np.eye.

CodePudding user response:

A simple solution using numpy.fliplr:

def get_diags(a, row=1, col=2):
    d1 = a.diagonal(col - row)
    h,w = a.shape
    d2 = np.fliplr(a).diagonal(w-col-1-row)
    return d1, d2[::-1]

get_diags(a, 1, 1)
# (array([ 1,  7, 13, 19]), array([11,  7,  3]))

get_diags(a, 1, 3)
# (array([ 3,  9, 15]), array([17, 13,  9,  5]))

get_diags(a, 2, 0)
# (array([11, 17]), array([11,  7,  3]))

One liner for the second diagonal:

np.fliplr(a).diagonal(a.shape[1]-col-1-row)[::-1]
  • Related