假如我们希望得到一个数组所有可能的行置换的结果,如对于一个三维数组:
a = [[1 3 5]
[2 4 6]
[7 8 9]]
当前状态记为(1 2 3)
其置换后的结果可表示为(1 3 2) (2 1 3)
等等。最简单直接的做法是循环嵌套,但这样代码过于冗长,执行速度慢。可借助itertools
库下的permutations()
方法来实现:
import numpy as np
import itertools
a = np.array([[1, 3, 5],
[2, 4, 6],
[7, 8, 9]])
index = np.linspace(0, 2, 3) # [0. 1. 2.]
permutations = list(itertools.permutations(index)) # generate all permutations of index
permuted_indexes = np.array(permutations, dtype=int) # [[0 1 2] [0 2 1] ...]
print(permuted_indexes)
先得到所有置换的索引:
[[0 1 2]
[0 2 1]
[1 0 2]
[1 2 0]
[2 0 1]
[2 1 0]]
需要指出,itertools.permutations
生成排列的顺序是按字典序排列的,如果原始序列是按升序排列的,那么生成的排列也是按升序排列的,通过下图就可以明白。若a = [1 2 3 4]
,则itertools.permutations(a)
得到的结果顺序为:
然后就可以遍历所有索引,得到所有置换后的数组:
a0 = a.copy()
for i in range(permuted_indexes.shape[0]): # permuted_indexes.shape[0] = n!
for j in range(a.shape[0]):
a[j, :] = a0[permuted_indexes[i, j], :]
print("a{:}={:}".format(i, a))
运行结果:
a0=[[1 3 5]
[2 4 6]
[7 8 9]]
a1=[[1 3 5]
[7 8 9]
[2 4 6]]
a2=[[2 4 6]
[1 3 5]
[7 8 9]]
a3=[[2 4 6]
[7 8 9]
[1 3 5]]
a4=[[7 8 9]
[1 3 5]
[2 4 6]]
a5=[[7 8 9]
[2 4 6]
[1 3 5]]
这样就得到了所有数组 a 的全部行置换的结果。实际上,可以直接对数组 a 进行操作:
import numpy as np
import itertools
a = np.array([[1, 3, 5],
[2, 4, 6],
[7, 8, 9]])
permutations = list(itertools.permutations(a)) # generate all permutations of index
permuted_arr = np.array(permutations) # [[0 1 2] [0 2 1] ...]
for i in range(permuted_arr.shape[0]):
print("a{:}={:}".format(i, permuted_arr[i]))
结果同上。