Home > Blockchain >  Permuting entire rows in a 2d numpy array
Permuting entire rows in a 2d numpy array

Time:01-19

Consider numpy array arr , shown below:

    arr = ([[1, 5, 6, 3, 3, 7],
            [2, 2, 2, 2, 2, 2],
            [0, 1, 0, 1, 0, 1],
            [4, 8, 4, 8, 4, 8],
            [1, 2, 3, 4, 5, 6]])

I want to find all row permutations of arr. NOTE: the order of elements in any given row is unchanged. It is the entire rows that are being permuted.

Because arr has 5 rows, there will be 5! = 120 permutations. I’m hoping these could be ‘stacked’ into a 3d array p, having shape (120, 5, 6):

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

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

       … etc …

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

There is a lot of material online about permitting elements within rows, but I need help in permuting the entire rows themselves.

CodePudding user response:

You can make use of itertools.permutations and np.argsort:

from itertools import permutations
out = np.array([arr[np.argsort(idx)] for idx in permutations(range(5))])

print(out)

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

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

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

 ...

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

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

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

CodePudding user response:

Similar answer, but you do not need to .argsort one more time

from itertools import permutations
import numpy as np

arr = np.array([[1, 5, 6, 3, 3, 7],
                [2, 2, 2, 2, 2, 2],
                [0, 1, 0, 1, 0, 1],
                [4, 8, 4, 8, 4, 8],
                [1, 2, 3, 4, 5, 6]])
output = np.array([arr[i, :] for i in permutations(range(5))])
print(output)

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

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

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

 ...

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

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

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

This is a bit faster, here are speed comparisons:

%%timeit
output = np.array([arr[i, :] for i in permutations(range(5))])
381 µs ± 14.9 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%%timeit
output = np.array([arr[np.argsort(idx)] for idx in permutations(range(5))])
863 µs ± 97.7 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
  • Related