二维数组所有元素的所有组合
All combinations of all elements of a 2D array
所以我有矩阵A
A = [[0,0,1,-1]
[0,0,1,-1]
[0,0,1,-1]
[0,0,1,-1]]
而且我想拥有这些元素的所有可能组合。这意味着行和列之间也可以更改。在这种情况下,我希望有 4^4 = 256
种可能性。我试过:
combs = np.array(list(itertools.product(*A)))
它确实创造了我,我想要输出一个 (256,4)
的矩阵,但是所有的行都是相等的。这意味着我得到向量 [0,0,1,-1]
、256
次。
这是一个例子:
output = [[0,0,0,0]
[0,0,0,1]
[0,0,1,1]
[0,1,1,1]
[1,1,1,1]
[-1,1,1,-1]
[-1,-1,-1,-1]
....
[0,-1,0,-1]
再举个例子,如果
A = [[1,2,3]
[4,5,6]
[7,8,9]]
输出应该是矩阵可以组成的所有可能的数组组合
Combs =[[1,1,1]
[1,1,2]
[1,1,3]
[1,1,...9]
[2,1,1]
[2,2,1]
[1,2,1]
另一个例子是:
我有矢量图层
layers = [1,2,3,4,5]
然后我有向量角
angle = [0,90,45,-45]
每一层都可以有一个角度,所以我创建了一个矩阵A
A = [[0,90,45,-45]
[0,90,45,-45]
[0,90,45,-45]
[0,90,45,-45]
[0,90,45,-45]]
很好,但现在我想知道图层可以具有的所有可能组合。例如,第 1 层的角度为 0º,第 2 层的角度为 90º,第 3 层的角度为 0º,第 4 层的角度为 45º,第 5 层的角度为 0º。这将创建数组
Comb = [0,90,0,45,0]
所以所有的组合都会在一个矩阵中
Comb = [[0,0,0,0,0]
[0,0,0,0,90]
[0,0,0,90,90]
[0,0,90,90,90]
[0,90,90,90,90]
[90,90,90,90,90]
...
[0,45,45,45,45]
[0,45,90,-45,90]]
如何将此过程推广到更大的矩阵。
我是不是做错了什么?
谢谢!
可以将 np.array
与 list
(iterable) 结合使用,尤其是在 iterable[=38] 的情况下=] 是 itertools.product(*A)
。但是,这可以优化,因为您知道输出数组的形状。
有很多方法可以执行product
所以我只列出我的列表:
笛卡尔积的方法
import itertools
import numpy as np
def numpy_product_itertools(arr):
return np.array(list(itertools.product(*arr)))
def numpy_product_fromiter(arr):
dt = np.dtype([('', np.intp)]*len(arr)) #or np.dtype(','.join('i'*len(arr)))
indices = np.fromiter(itertools.product(*arr), dt)
return indices.view(np.intp).reshape(-1, len(arr))
def numpy_product_meshgrid(arr):
return np.stack(np.meshgrid(*arr), axis=-1).reshape(-1, len(arr))
def numpy_product_broadcast(arr): #a little bit different type of output
items = [np.array(item) for item in arr]
idx = np.where(np.eye(len(arr)), Ellipsis, None)
out = [x[tuple(i)] for x,i in zip(items, idx)]
return list(np.broadcast(*out))
用法示例
A = [[1,2,3], [4,5], [7]]
numpy_product_itertools(A)
numpy_product_fromiter(A)
numpy_product_meshgrid(A)
numpy_product_broadcast(A)
性能比较
import benchit
benchit.setparams(rep=1)
%matplotlib inline
sizes = [3,4,5,6,7]
N = sizes[-1]
arr = [np.arange(0,100,10).tolist()] * N
fns = [numpy_product_itertools, numpy_product_fromiter, numpy_product_meshgrid, numpy_product_broadcast]
in_ = {s: (arr[:s],) for s in sizes}
t = benchit.timings(fns, in_, multivar=True, input_name='Cartesian product of N arrays of length=10')
t.plot(logx=False, figsize=(12, 6), fontsize=14)
请注意,numba
击败了大多数这些算法,尽管它不包括在内。
所以我有矩阵A
A = [[0,0,1,-1]
[0,0,1,-1]
[0,0,1,-1]
[0,0,1,-1]]
而且我想拥有这些元素的所有可能组合。这意味着行和列之间也可以更改。在这种情况下,我希望有 4^4 = 256
种可能性。我试过:
combs = np.array(list(itertools.product(*A)))
它确实创造了我,我想要输出一个 (256,4)
的矩阵,但是所有的行都是相等的。这意味着我得到向量 [0,0,1,-1]
、256
次。
这是一个例子:
output = [[0,0,0,0]
[0,0,0,1]
[0,0,1,1]
[0,1,1,1]
[1,1,1,1]
[-1,1,1,-1]
[-1,-1,-1,-1]
....
[0,-1,0,-1]
再举个例子,如果
A = [[1,2,3]
[4,5,6]
[7,8,9]]
输出应该是矩阵可以组成的所有可能的数组组合
Combs =[[1,1,1]
[1,1,2]
[1,1,3]
[1,1,...9]
[2,1,1]
[2,2,1]
[1,2,1]
另一个例子是: 我有矢量图层
layers = [1,2,3,4,5]
然后我有向量角
angle = [0,90,45,-45]
每一层都可以有一个角度,所以我创建了一个矩阵A
A = [[0,90,45,-45]
[0,90,45,-45]
[0,90,45,-45]
[0,90,45,-45]
[0,90,45,-45]]
很好,但现在我想知道图层可以具有的所有可能组合。例如,第 1 层的角度为 0º,第 2 层的角度为 90º,第 3 层的角度为 0º,第 4 层的角度为 45º,第 5 层的角度为 0º。这将创建数组
Comb = [0,90,0,45,0]
所以所有的组合都会在一个矩阵中
Comb = [[0,0,0,0,0]
[0,0,0,0,90]
[0,0,0,90,90]
[0,0,90,90,90]
[0,90,90,90,90]
[90,90,90,90,90]
...
[0,45,45,45,45]
[0,45,90,-45,90]]
如何将此过程推广到更大的矩阵。
我是不是做错了什么?
谢谢!
可以将 np.array
与 list
(iterable) 结合使用,尤其是在 iterable[=38] 的情况下=] 是 itertools.product(*A)
。但是,这可以优化,因为您知道输出数组的形状。
有很多方法可以执行product
所以我只列出我的列表:
笛卡尔积的方法
import itertools
import numpy as np
def numpy_product_itertools(arr):
return np.array(list(itertools.product(*arr)))
def numpy_product_fromiter(arr):
dt = np.dtype([('', np.intp)]*len(arr)) #or np.dtype(','.join('i'*len(arr)))
indices = np.fromiter(itertools.product(*arr), dt)
return indices.view(np.intp).reshape(-1, len(arr))
def numpy_product_meshgrid(arr):
return np.stack(np.meshgrid(*arr), axis=-1).reshape(-1, len(arr))
def numpy_product_broadcast(arr): #a little bit different type of output
items = [np.array(item) for item in arr]
idx = np.where(np.eye(len(arr)), Ellipsis, None)
out = [x[tuple(i)] for x,i in zip(items, idx)]
return list(np.broadcast(*out))
用法示例
A = [[1,2,3], [4,5], [7]]
numpy_product_itertools(A)
numpy_product_fromiter(A)
numpy_product_meshgrid(A)
numpy_product_broadcast(A)
性能比较
import benchit
benchit.setparams(rep=1)
%matplotlib inline
sizes = [3,4,5,6,7]
N = sizes[-1]
arr = [np.arange(0,100,10).tolist()] * N
fns = [numpy_product_itertools, numpy_product_fromiter, numpy_product_meshgrid, numpy_product_broadcast]
in_ = {s: (arr[:s],) for s in sizes}
t = benchit.timings(fns, in_, multivar=True, input_name='Cartesian product of N arrays of length=10')
t.plot(logx=False, figsize=(12, 6), fontsize=14)
请注意,numba
击败了大多数这些算法,尽管它不包括在内。