【问题标题】:All combinations of all elements of a 2D array二维数组的所有元素的所有组合
【发布时间】:2022-01-25 07:34:33
【问题描述】:

所以我有矩阵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]]

如何将这个过程推广到更大的矩阵。

我做错了吗?

谢谢!

【问题讨论】:

  • 我相信你的A 已经有相同的行了?
  • angle_ 是什么?
  • @richardec 我已经编辑了帖子。它是创建我的矩阵 A 的数组之一。
  • 那么您的预期输出是什么?通过运行您的代码,我得到了一个形状数组 (4, 1, 4)
  • @PedroBrandão。您能否列出那些与您没有相同期望的人的可能性?你的散文和代码没有明确匹配。

标签: python numpy combinations


【解决方案1】:

可以将 np.arraylist(iterable) 结合使用,尤其是在 iterableitertools.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 胜过大多数这些算法,尽管它不包括在内。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多