I would like to be able to generate all unique permutations of a 2d array in python and keep the order. Let's say I have a 2D matrix [[1, 2, 3], [4, 5, 6]]
. Expected result should be a in 8 x 3 in the form [[1, 2, 3],
[1, 2, 6],
[1, 5, 3],
[1, 5, 6],
[4, 2, 3],
[4, 2, 6],
[4, 5, 3],
[4, 5, 6]]
.
Thanks
Transpose the array , and then use itertools.product
:
from itertools import product
list(map(list, product(*zip(*data))))
This outputs:
[[1, 2, 3], [1, 2, 6], [1, 5, 3], [1, 5, 6], [4, 2, 3], [4, 2, 6], [4, 5, 3], [4, 5, 6]]
You can use zip
to transpose 2D list
and itertools.product
.
>>> from itertools import product
>>> lst = [[1, 2, 3], [4, 5, 6]]
>>> list(product(*(zip(*lst))))
# If you want to get each `tuple` as `list`
# >>> list(map(list, product(*zip(*lst))))
[(1, 2, 3),
(1, 2, 6),
(1, 5, 3),
(1, 5, 6),
(4, 2, 3),
(4, 2, 6),
(4, 5, 3),
(4, 5, 6)]
The itertools method with product would be the most readible way to do this, but since your question is tagged numpy , here is how you can do this using only Numpy methods.
You can use this method if order is not important for you. This uses np.meshgrid
and np.stack
with some .reshape
to get the permutations you need, minus the order you expect.
import numpy as np
lst = [[1, 2, 3], [4, 5, 6]]
arr = np.array(lst)
np.stack(np.meshgrid(*arr.T),-1).reshape(-1,3)
array([[1, 2, 3],
[1, 2, 6],
[4, 2, 3],
[4, 2, 6],
[1, 5, 3],
[1, 5, 6],
[4, 5, 3],
[4, 5, 6]])
Getting the order to work is a bit "hacky" but a small modification over the above array with simple reordering of columns can solve this with pretty much the same code.
import numpy as np
lst = [[1, 2, 3], [4, 5, 6]]
order = [1,0,2]
arr = np.array(lst)[:,order]
np.stack(np.meshgrid(*arr.T),-1).reshape(-1,3)[:,order]
array([[1, 2, 3],
[1, 2, 6],
[1, 5, 3],
[1, 5, 6],
[4, 2, 3],
[4, 2, 6],
[4, 5, 3],
[4, 5, 6]])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.