【问题标题】:Make every possible combination in 2D array在二维数组中制作所有可能的组合
【发布时间】:2017-02-17 14:40:50
【问题描述】:

我正在尝试制作具有所有可能组合的 4x4 (16) 像素黑白图像阵列。我将以下数组作为模板:

template = [[0,0,0,0],    # start with all white pixels
            [0,0,0,0],    
            [0,0,0,0],
            [0,0,0,0]]

然后我想遍历模板并将每个可能的组合的 0 更改为 1。 我尝试使用 numpy 和 itertools 进行迭代,但只能得到 256 个组合,并且根据我的计算应该有 32000(编辑:65536!不知道那里发生了什么......)。任何有疯狂技能的人可以帮助我吗?

【问题讨论】:

  • 顺便说一句,不应该有65536个组合(2**16),而不仅仅是32000个?

标签: python arrays numpy


【解决方案1】:

如您所说,您可以使用itertools 模块来执行此操作,尤其是product 函数:

import itertools
import numpy as np

# generate all the combinations as string tuples of length 16
seq = itertools.product("01", repeat=16)

for s in seq:
    # convert to numpy array and reshape to 4x4
    arr = np.fromiter(s, np.int8).reshape(4, 4)
    # do something with arr

【讨论】:

    【解决方案2】:

    您将总共有65536 这样一个 (4 x 4) 形状的阵列的组合。这是生成所有这些组合的矢量化方法,为我们提供(65536 x 4 x 4) 形状的多维数组 -

    mask = ((np.arange(2**16)[:,None] & (1 << np.arange(16))) != 0)
    out = mask.astype(int).reshape(-1,4,4)
    

    示例运行 -

    In [145]: out.shape
    Out[145]: (65536, 4, 4)
    
    In [146]: out
    Out[146]: 
    array([[[0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]],
    
           [[1, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]],
    
           [[0, 1, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]],
    
           ..., 
           [[1, 0, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]],
    
           [[0, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]],
    
           [[1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]]])
    

    【讨论】:

      【解决方案3】:

      一种依赖于 for 循环的可能性

      out = []
      for i in range(2**16):
         out.append(np.frombuffer("{:016b}".format(i).encode('utf8')).view(np.uint8).reshape(4,4)-48)
      

      如果你愿意的话,显然你可以把它变成一个列表理解。

      它利用了 Python 字符串格式,能够生成整数的二进制表示。格式字符串指示它使用左侧用零填充的 16 个位置。然后对该字符串进行编码以提供一个字节对象,numpy 可以将其解释为数组。

      最后,我们减去字符“0”的代码以获得正确的 0。幸运的是,“1”正好位于“0”的上方,所以这就是我们需要做的所有事情。

      【讨论】:

        【解决方案4】:

        首先,我将迭代从 0 到 (2^16)-1 的所有数字。然后我将为每个数字创建一个 16 字符的二进制字符串,从而涵盖所有可能的组合

        之后,我将字符串转换为列表,并使用列表理解和切片从中创建了一个二维列表。

        all_combinations = []
        
        for i in xrange(pow(2,16))
            binary = '{0:016b}'.format(i)  ## Converted number to binary string
            binary = map(int,list(binary))  ## String to list ## list(map(int,list(binary))) in py 3
            template = [binary[i:i+4] for i in xrange(0, len(binary), 4)] #created 2d list
            all_combinations.append(template)
        

        【讨论】:

        • 你能解释一下你做了什么以及它是如何工作的吗?
        猜你喜欢
        • 2019-04-18
        • 1970-01-01
        • 2012-07-04
        • 2011-05-30
        • 2014-02-24
        • 2017-03-27
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多