Columnar permutations in Python

Question:

How would I can find all the permutations of just the columns in a matrix. For example – if I had a square 6×6 matrix like so:

   a   b   c   d   e   f

1: 75  62  82  85  91  85

2: 64  74  74  82  74  64

3: 85  81  91  83  91  62

4: 91  63  81  75  75  72

5: 81  91  74  74  91  63

6: 91  72  81  64  75  72

All the numbers in each column – abcdef – would stay with that column as it moved through the columnar permutations.

Asked By: Xcelsior333

||

Answers:

Here’s how I represented your data… you seem to want rows, but the permutation you want is in columns. Here it is as a list of lists, of the rows first:

row_matrix = [[75, 62, 82, 85, 91, 85],
 [64, 74, 74, 82, 74, 64],
 [85, 81, 91, 83, 91, 62],
 [91, 63, 81, 75, 75, 72],
 [81, 91, 74, 74, 91, 63],
 [91, 72, 81, 64, 75, 72]]

You can use numpy to easily transpose a 2D array of (rows x columns) –> (columns x rows) by converting the list to a numpy array and applying .T. I’ll use that here, but will push things back into Python lists using .tolist() to keep it simpler for you.

import numpy as np

column_matrix = np.array(row_matrix).T.tolist()

Next, you need a list of the column numbers — 0 through 5 in your case. I used integers instead of calling them "a" through "f" to facilitate indexing below… you can always assign the alpha names to them later (…but if you’d rather keep that labeling around the whole time, you can work with Python dictionaries instead):

columns = list(range(len(column_matrix)))

# print(columns)
# shows --> [0, 1, 2, 3, 4, 5]

For the permutations, there is a built-in library for generating them, as part of itertools. The primary index of the list of lists is now the column numbers, so if we generate the permutations of the column number order, we can build all the 2D matrices from that. After that, you can just transpose them again to get it back to the original row-wise data structure:

from itertools import permutations

all_permutations = []
for perm in itertools.permutations(columns):
    shuffled_column_matrix = []
    for idx in perm:
        shuffled_column_matrix.append(column_matrix[idx])
    all_permutations.append( np.array(shuffled_column_matrix).T.tolist() )

The above can be done in a slightly more compact way using a list-comprehension:

#all_permutations = []
#for perm in itertools.permutations(columns):
#    shuffled_column_matrix = np.array( [ column_matrix[idx] for idx in perm ] )
#    all_permutations.append( shuffled_column_matrix.T.tolist() )  

When it finishes all_permutations is a list of all the column-wise permutations, represented as row-wise matrices similar to the input.

Answered By: Rick M

From an array:

import numpy as np
arr = np.arange(9).reshape(3,3)

For columns:

import itertools

for i in itertools.permutations(arr.T):
    i = np.asarray(i).T

For rows (if anyone needs rows instead):

import itertools

for i in itertools.permutations(arr):
    i = np.asarray(i)
Answered By: Wychh