Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an easier way to produce a numpy matrix where the numbers worm up and down vertically

I'm sorry I don't know the correct terminology hence 'worm vertically' basically I want the numbers to start at the bottom left and as it goes up the column it adds, then the next column has its lowest number at the top and adds as it goes down. eg:

[2, 3, 8
 1, 4, 7
 0, 5, 6]

so far I came up with this very bloated code that basically makes a column then copies it, flips it, adds the max value of the last column plus 1, then hstack's them together eg:

first column

[2,
 1,
 0,]

flip it:

[0,
 1,
 2,]

add the max value of the last plus 1 (3 in this case):

 [3,
  4,
  5,]

hstack them:

[2, 3
 1, 4
 0, 5]

I then just repeat this for as many columns I want. to speed things up, if I wanted 4 I can just take the final hstack and copy both columns and add the max value. no flipping is needed because its an even number of columns.

The matrix I need has 252 items in a 12 by 21 matrix. This is the code I have so far:

import numpy as np

a = np.arange(20,-1,-1).reshape(21,1)
b = a+1 + a[::-1]*2
c = b+1 + a*2
d = np.hstack((a,b,c))
e = np.hstack((d,np.flip(d,0)+ d.shape[0] * d.shape[1]))
f = np.hstack((e,e + e.shape[0] * e.shape[1]))
del a,b,c,d,e

>>> f
array([[ 20,  21,  62,  63, 104, 105, 146, 147, 188, 189, 230, 231],
       [ 19,  22,  61,  64, 103, 106, 145, 148, 187, 190, 229, 232],
       [ 18,  23,  60,  65, 102, 107, 144, 149, 186, 191, 228, 233],
       [ 17,  24,  59,  66, 101, 108, 143, 150, 185, 192, 227, 234],
       [ 16,  25,  58,  67, 100, 109, 142, 151, 184, 193, 226, 235],
       [ 15,  26,  57,  68,  99, 110, 141, 152, 183, 194, 225, 236],
       [ 14,  27,  56,  69,  98, 111, 140, 153, 182, 195, 224, 237],
       [ 13,  28,  55,  70,  97, 112, 139, 154, 181, 196, 223, 238],
       [ 12,  29,  54,  71,  96, 113, 138, 155, 180, 197, 222, 239],
       [ 11,  30,  53,  72,  95, 114, 137, 156, 179, 198, 221, 240],
       [ 10,  31,  52,  73,  94, 115, 136, 157, 178, 199, 220, 241],
       [  9,  32,  51,  74,  93, 116, 135, 158, 177, 200, 219, 242],
       [  8,  33,  50,  75,  92, 117, 134, 159, 176, 201, 218, 243],
       [  7,  34,  49,  76,  91, 118, 133, 160, 175, 202, 217, 244],
       [  6,  35,  48,  77,  90, 119, 132, 161, 174, 203, 216, 245],
       [  5,  36,  47,  78,  89, 120, 131, 162, 173, 204, 215, 246],
       [  4,  37,  46,  79,  88, 121, 130, 163, 172, 205, 214, 247],
       [  3,  38,  45,  80,  87, 122, 129, 164, 171, 206, 213, 248],
       [  2,  39,  44,  81,  86, 123, 128, 165, 170, 207, 212, 249],
       [  1,  40,  43,  82,  85, 124, 127, 166, 169, 208, 211, 250],
       [  0,  41,  42,  83,  84, 125, 126, 167, 168, 209, 210, 251]])

Is there a super simple way of doing this that I'm not seeing or don't know?

like image 507
Whud Avatar asked Dec 17 '22 23:12

Whud


1 Answers

You can transpose the array and flip vertically every second column:

import numpy as np
row = 4
col = 5
a = np.transpose(np.arange(row * col).reshape(col, row))
a[:, ::2] = np.flipud(a[:, ::2])

print(a)
#Output
[[ 3  4 11 12 19]
 [ 2  5 10 13 18]
 [ 1  6  9 14 17]
 [ 0  7  8 15 16]]

There is of course also a horizontal version of this flip function.

like image 183
Mr. T Avatar answered Mar 15 '23 23:03

Mr. T