11

I have a NumPy matrix which I've simplified to exemplify:

       a  b  c  d  e  f 
A =  [[0, 1, 2, 3, 4, 5],
 b    [1, 0, 3, 4, 5, 6],
 c    [2, 3, 0, 5, 6, 7],
 d    [3, 4, 5, 0, 7, 8],
 e    [4, 5, 6, 7, 0, 9],
 f    [5, 6, 7, 8, 9, 0]]

where the number at the "intersections" is important, but their order is not right. I want to re-arrange the rows and columns such that the new order is [a, d, b, e, c, f] but this value that I'm calling "the intersection" is the same.

Below I have started to transform the matrix how I want. Filling the 'e' row involves looking at the intersections above for (e,a) (= 4), then (e,d) (=7) , then (e,b) (=5), (e,e), (e,c), and (e,f)

       a  d  b  e  c  f
A1=  [[0, 3, 1, 4, 2, 5],
 d    [3, 0, 4, 7, 5, 8],
 b    [1, 4, 0, 5, 3, 6],  
 e    [4, 7, 5, 

Can anyone please suggest how to re-arrange my matrix in this manner?

emmagras
  • 1,378
  • 2
  • 18
  • 25

2 Answers2

19

edit: I just stumbled across a NumPy solution that uses advanced indexing:

#                 a  b  c  d  e  f
A = numpy.array([[0, 1, 2, 3, 4, 5],
                 [1, 0, 3, 4, 5, 6],
                 [2, 3, 0, 5, 6, 7],
                 [3, 4, 5, 0, 7, 8],
                 [4, 5, 6, 7, 0, 9],
                 [5, 6, 7, 8, 9, 0]])

#            a  d  b  e  c  f
new_order = [0, 3, 1, 4, 2, 5]
A1 = A[:, new_order][new_order]

Here is a pure Python solution which may be transferable to NumPy:

#     a  b  c  d  e  f
A = [[0, 1, 2, 3, 4, 5],
     [1, 0, 3, 4, 5, 6],
     [2, 3, 0, 5, 6, 7],
     [3, 4, 5, 0, 7, 8],
     [4, 5, 6, 7, 0, 9],
     [5, 6, 7, 8, 9, 0]]

#            a  d  b  e  c  f
new_order = [0, 3, 1, 4, 2, 5]    # maps previous index to new index
A1 = [[A[i][j] for j in new_order] for i in new_order]

Result:

>>> pprint.pprint(A1)
[[0, 3, 1, 4, 2, 5],
 [3, 0, 4, 7, 5, 8],
 [1, 4, 0, 5, 3, 6],
 [4, 7, 5, 0, 6, 9],
 [2, 5, 3, 6, 0, 7],
 [5, 8, 6, 9, 7, 0]]

Here is a version that modifies A in place:

A[:] = [A[i] for i in new_order]
for row in A:
    row[:] = [row[i] for i in new_order]
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
  • A thing of beauty. That accomplishes exactly what I was looking for, and quite compactly too. I don't understand "pprint.pprint", though. Also, your comments made the answer even easier to read. As a newb, I appreciate it. – emmagras Jun 07 '12 at 17:56
  • @wagras - [`pprint`](http://docs.python.org/library/pprint.html) is a module for "pretty-printing" data, it is just a simple way to print arrays and dictionaries in that row/column format, instead of just on a single line. – Andrew Clark Jun 07 '12 at 17:57
  • @wagras - In case you didn't see my edit, I found a more concise solution for NumPy. – Andrew Clark Jun 07 '12 at 18:04
  • I've been watching all your updates. :D Can't thank you enough for your thoroughness. – emmagras Jun 07 '12 at 18:06
3

Numpy provides many methods to manipulate arrays, including rolling elements along an xis, rolling all axes, swap axes. You can use a combination of these to get the desired order of elements

Dhara
  • 6,587
  • 2
  • 31
  • 46