I have a n x n array, and want to receive its outline values. For example,
[4,5,6,7]
[2,2,6,3]
[4,4,9,4]
[8,1,6,1]
from this, i would get this
[4,5,6,7,3,4,1,6,1,8,4,2]
(see where bold)
So essentially, what is the most efficient way of getting a 1D array of all the values going around the edges of a 2D array? I ask because I assume there is a numPy function that helps with this (which I haven't yet found!), instead of doing it manually with loops?
In [1]: arr=np.arange(16).reshape(4,4)
In [2]: arr
Out[2]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
A relatively straight forward way of doing this - in clockwise order is:
In [5]: alist=[arr[0,:-1], arr[:-1,-1], arr[-1,::-1], arr[-2:0:-1,0]]
In [6]: alist
Out[6]: [array([0, 1, 2]), array([ 3, 7, 11]), array([15, 14, 13, 12]), array([8, 4])]
In [7]: np.concatenate(alist)
Out[7]: array([ 0, 1, 2, 3, 7, 11, 15, 14, 13, 12, 8, 4])
In a sense it's a loop, in that I have to build 4 slices. But if 4 is small compared to n
, that's a small price. It has to concatenate at some level.
If order doesn't matter we could simplify the slices some (e.g. forgetting the reverse order, etc).
alist=[arr[0,:], arr[1:,-1], arr[-1,:-1], arr[1:-1,0]]
If I didn't care about order, or double counting the corners I could use:
np.array([arr[[0,n],:], arr[:,[0,n]].T]).ravel()
eliminating the duplicate corners
In [18]: np.concatenate((arr[[0,n],:].ravel(), arr[1:-1,[0,n]].ravel()))
Out[18]: array([ 0, 1, 2, 3, 12, 13, 14, 15, 4, 7, 8, 11])