Python numpy array fold matrix when accessed out of bound

Viewed 241

How do I acheive numpy array folding in Python?

e.g.:

A = [[ 0,  1,  2,  3],
     [ 4,  5,  6,  7],
     [ 8,  9, 10, 11],
     [12, 13, 14, 15]]

My desired output for this pseudo-code:

A[-1 to 1, -1 to 2] = [[15, 12, 13],
                       [ 3,  0,  1]]

I tried A[i % 4 for i in range(-1, 1), j % 4 for j in range(-1, 2)] but it is not a valid numpy operation.

2 Answers

Please try this:

import numpy as np

A =np.array([[ 0,  1,  2,  3],
   [ 4,  5,  6,  7],
   [ 8,  9, 10, 11],
   [12, 13, 14, 15]])
b=[ [A[(3+i)%A.shape[0],(3+j)%A.shape[1]] for j in range(3)] for i in range(2)]
print(b)

The output is:

[[15, 12, 13], [3, 0, 1]]

You can easily achieve that by using np.ix_ and range():

import numpy as np

A =np.array([[ 0,  1,  2,  3],
             [ 4,  5,  6,  7],
             [ 8,  9, 10, 11],
             [12, 13, 14, 15]])

A[np.ix_(range(-1,1),range(-1,2))]

Output:

array([[15, 12, 13],
       [ 3,  0,  1]])

To avoid the possible error in a scenario like when for example the range of the sliced is (5,5) in a 4x4 matrix, you could try this:

import numpy as np

A =np.array([[ 0,  1,  2,  3],
             [ 4,  5,  6,  7],
             [ 8,  9, 10, 11],
             [12, 13, 14, 15]])
s1=[5,5]
s1=list(map(lambda x:(x+A.shape[0])%A.shape[0],s1)) if s1[0]>s1[1] else s1
s1=list(map(lambda x:(x+A.shape[0])%A.shape[0],range(min(s1),max(s1)))) if s1[0]%A.shape[0]!=s1[1]%A.shape[0] else [(s1[0]+A.shape[0])%A.shape[0]]

s2=[-1,2]
s2=list(map(lambda x:(x+A.shape[0])%A.shape[0],s2)) if s2[0]>s2[1] else s2
s2=list(map(lambda x:(x+A.shape[0])%A.shape[0],range(min(s2),max(s2)))) if s2[0]%A.shape[0]!=s2[1]%A.shape[0] else [(s2[0]+A.shape[0])%A.shape[0]]

A[np.ix_(s1,s2)]
Related