【问题标题】:Generate all unique permutations of 2d array生成二维数组的所有唯一排列
【发布时间】:2014-02-22 19:43:34
【问题描述】:

我希望能够在 python 中生成二维数组的所有唯一排列。

以这个二维数组为例 [[1,1],[0,0]] 我想回来

[[0,0],
[1,1]]

[[0,1],
[0,1]]

[[0,1]
[1,0]]

[[1,0]
[0,1]]

[[1,0]
[1,0]]

[[1,1]
[0,0]]

【问题讨论】:

  • 二维数组的排列如何?我只能看到您创建了四个数字的排列1,1,0,0 并将每个排列拆分为两个数组。
  • 我看不出这是怎么复制的。另一个问题是关于获得笛卡尔积。两者完全不同。
  • 确实不是那个的复制品,而是stackoverflow.com/questions/104420/…的复制品
  • @zmo 是的,它更接近那个,但我相信我们不能认为这是这个问题的一个重复。我们这里有两个列表,OP 只想要唯一的排列。
  • 好吧,基于那个 dup,并使用 py3,他想要这个:print (set(tuple([ ((p[0],p[1]),(p[2],p[3])) for p in itertools.permutations([1,1,0,0])])))

标签: python


【解决方案1】:

你可以这样做

d = [[1, 1], [0, 0]]
from itertools import permutations, chain
from pprint import pprint
pprint(sorted([i[:2], i[2:]] for i in set(permutations(chain.from_iterable(d)))))

输出

[[[0, 0], [1, 1]],
 [[0, 1], [0, 1]],
 [[0, 1], [1, 0]],
 [[1, 0], [0, 1]],
 [[1, 0], [1, 0]],
 [[1, 1], [0, 0]]]

【讨论】:

    【解决方案2】:

    这是您数组的大致大小吗?如果它很大,这个解决方案将非常缓慢,但最终会起作用。对于这种大小的数组,python 内置的 itertools 是可行的方法,再加上一些 numpy 操作。

    此外,唯一排列的数量取决于初始数组中不同元素的数量。因此,将数组展平,产生所有排列,重新整形为 2x2(或您想要的大小),然后比较会得到“独特”的数组,正如您的意思。

    我在这里使用了循环(而不是推导式)来使事情易于阅读/测试/检查。在你真正使用之前,一定要转化为理解(更快,更好)。

    a = np.array([[1,1],[0,0]]).flatten()
    permutes = []
    for i in permutations(a):
        permutes.append((np.array(i).reshape((2,2))))
    
    unique_permutes = [permutes[0]]
    for i in permutes[1:]:
        one_equal = False
        for unique in unique_permutes:
            if np.array_equal(i, unique):
                one_equal = True
                break
        if not one_equal:
            unique_permutes.append(i)
    
    print len(unique_permutes) #same as what you wanted
    for i in unique_permutes: #prints pretilly for sanity checking
        print i
    

    【讨论】:

    • 最好使用列表理解而不是 appending 到列表。
    • 已编辑——我用循环编写了这个,用于测试/可读性等。
    【解决方案3】:

    一个 - 不是特别有效 - 这样做的方法是

    from itertools import permutations, chain, islice
    
    def uniperm_arrays(arr):
        flat = chain.from_iterable(arr)
        perms = set(permutations(flat))
        for perm in perms:
            pit = iter(perm)
            yield [list(islice(pit, len(row))) for row in arr]
    

    给了

    >>> uu = uniperm_arrays([[1,1],[0,0]])
    >>> for u in uu:
    ...     for row in u:
    ...         print(row)
    ...     print()
    ...     
    [1, 0]
    [1, 0]
    
    [1, 1]
    [0, 0]
    
    [0, 0]
    [1, 1]
    
    [1, 0]
    [0, 1]
    
    [0, 1]
    [1, 0]
    
    [0, 1]
    [0, 1]
    

    【讨论】:

      【解决方案4】:

      EDIT这应该适用于任何尺寸和形状的二维数组。

      基于排列实际上只是构造为二维列表的平面数字序列的想法:

      from itertools import permutations
      
      def tbl_perms(table):
          flat = (j for i in table for j in i)
          flat_permutations = iter(sorted(set(permutations(flat))))
      
          # convert back to the original structure
          while flat_permutations:
              flat_table = list(flat_permutations.next())  # because you can't pop() from tuple
              yield [[flat_table.pop(0) for _ in row] for row in table]
      
      result = tbl_perms([[1, 1], [0, 0]])
      pprint(list(result))
      
      result = tbl_perms([[1, 1, 1], [0, 0, 0]])
      pprint(list(result))
      
      result = tbl_perms([[1, 2, 3], ['a', 'b']])
      pprint(list(result))
      

      输出:

      [[[0, 0], [1, 1]], [[0, 1], [0, 1]], [[0, 1], [1, 0]], [[1, 0], [0, 1]], [[1, 0], [1, 0]], [[1, 1], [0, 0]]]
      [[[0, 0, 0], [1, 1, 1]], [[0, 0, 1], [0, 1, 1]], [[0, 0, 1], [1, 0, 1]], [[0, 0, 1], [1, 1, 0]], [[0, 1, 0], [0, 1, 1]], [[0, 1, 0], [1, 0, 1]], [[0, 1, 0], [1, 1, 0]], [[0, 1, 1], [0, 0, 1]], [[0, 1, 1], [0, 1, 0]], [[0, 1, 1], [1, 0, 0]], [[1, 0, 0], [0, 1, 1]], [[1, 0, 0], [1, 0, 1]], [[1, 0, 0], [1, 1, 0]], [[1, 0, 1], [0, 0, 1]], [[1, 0, 1], [0, 1, 0]], [[1, 0, 1], [1, 0, 0]], [[1, 1, 0], [0, 0, 1]], [[1, 1, 0], [0, 1, 0]], [[1, 1, 0], [1, 0, 0]], [[1, 1, 1], [0, 0, 0]]]
      [[[1, 2, 3], ['a', 'b']], [[1, 2, 3], ['b', 'a']], [[1, 2, 'a'], [3, 'b']], [[1, 2, 'a'], ['b', 3]], [[1, 2, 'b'], [3, 'a']], [[1, 2, 'b'], ['a', 3]], [[1, 3, 2], ['a', 'b']], [[1, 3, 2], ['b', 'a']], [[1, 3, 'a'], [2, 'b']], [[1, 3, 'a'], ['b', 2]], [[1, 3, 'b'], [2, 'a']], [[1, 3, 'b'], ['a', 2]], [[1, 'a', 2], [3, 'b']], [[1, 'a', 2], ['b', 3]], [[1, 'a', 3], [2, 'b']], [[1, 'a', 3], ['b', 2]], [[1, 'a', 'b'], [2, 3]], [[1, 'a', 'b'], [3, 2]], [[1, 'b', 2], [3, 'a']], [[1, 'b', 2], ['a', 3]], [[1, 'b', 3], [2, 'a']], [[1, 'b', 3], ['a', 2]], [[1, 'b', 'a'], [2, 3]], [[1, 'b', 'a'], [3, 2]], [[2, 1, 3], ['a', 'b']], [[2, 1, 3], ['b', 'a']], [[2, 1, 'a'], [3, 'b']], [[2, 1, 'a'], ['b', 3]], [[2, 1, 'b'], [3, 'a']], [[2, 1, 'b'], ['a', 3]], [[2, 3, 1], ['a', 'b']], [[2, 3, 1], ['b', 'a']], [[2, 3, 'a'], [1, 'b']], [[2, 3, 'a'], ['b', 1]], [[2, 3, 'b'], [1, 'a']], [[2, 3, 'b'], ['a', 1]], [[2, 'a', 1], [3, 'b']], [[2, 'a', 1], ['b', 3]], [[2, 'a', 3], [1, 'b']], [[2, 'a', 3], ['b', 1]], [[2, 'a', 'b'], [1, 3]], [[2, 'a', 'b'], [3, 1]], [[2, 'b', 1], [3, 'a']], [[2, 'b', 1], ['a', 3]], [[2, 'b', 3], [1, 'a']], [[2, 'b', 3], ['a', 1]], [[2, 'b', 'a'], [1, 3]], [[2, 'b', 'a'], [3, 1]], [[3, 1, 2], ['a', 'b']], [[3, 1, 2], ['b', 'a']], [[3, 1, 'a'], [2, 'b']], [[3, 1, 'a'], ['b', 2]], [[3, 1, 'b'], [2, 'a']], [[3, 1, 'b'], ['a', 2]], [[3, 2, 1], ['a', 'b']], [[3, 2, 1], ['b', 'a']], [[3, 2, 'a'], [1, 'b']], [[3, 2, 'a'], ['b', 1]], [[3, 2, 'b'], [1, 'a']], [[3, 2, 'b'], ['a', 1]], [[3, 'a', 1], [2, 'b']], [[3, 'a', 1], ['b', 2]], [[3, 'a', 2], [1, 'b']], [[3, 'a', 2], ['b', 1]], [[3, 'a', 'b'], [1, 2]], [[3, 'a', 'b'], [2, 1]], [[3, 'b', 1], [2, 'a']], [[3, 'b', 1], ['a', 2]], [[3, 'b', 2], [1, 'a']], [[3, 'b', 2], ['a', 1]], [[3, 'b', 'a'], [1, 2]], [[3, 'b', 'a'], [2, 1]], [['a', 1, 2], [3, 'b']], [['a', 1, 2], ['b', 3]], [['a', 1, 3], [2, 'b']], [['a', 1, 3], ['b', 2]], [['a', 1, 'b'], [2, 3]], [['a', 1, 'b'], [3, 2]], [['a', 2, 1], [3, 'b']], [['a', 2, 1], ['b', 3]], [['a', 2, 3], [1, 'b']], [['a', 2, 3], ['b', 1]], [['a', 2, 'b'], [1, 3]], [['a', 2, 'b'], [3, 1]], [['a', 3, 1], [2, 'b']], [['a', 3, 1], ['b', 2]], [['a', 3, 2], [1, 'b']], [['a', 3, 2], ['b', 1]], [['a', 3, 'b'], [1, 2]], [['a', 3, 'b'], [2, 1]], [['a', 'b', 1], [2, 3]], [['a', 'b', 1], [3, 2]], [['a', 'b', 2], [1, 3]], [['a', 'b', 2], [3, 1]], [['a', 'b', 3], [1, 2]], [['a', 'b', 3], [2, 1]], [['b', 1, 2], [3, 'a']], [['b', 1, 2], ['a', 3]], [['b', 1, 3], [2, 'a']], [['b', 1, 3], ['a', 2]], [['b', 1, 'a'], [2, 3]], [['b', 1, 'a'], [3, 2]], [['b', 2, 1], [3, 'a']], [['b', 2, 1], ['a', 3]], [['b', 2, 3], [1, 'a']], [['b', 2, 3], ['a', 1]], [['b', 2, 'a'], [1, 3]], [['b', 2, 'a'], [3, 1]], [['b', 3, 1], [2, 'a']], [['b', 3, 1], ['a', 2]], [['b', 3, 2], [1, 'a']], [['b', 3, 2], ['a', 1]], [['b', 3, 'a'], [1, 2]], [['b', 3, 'a'], [2, 1]], [['b', 'a', 1], [2, 3]], [['b', 'a', 1], [3, 2]], [['b', 'a', 2], [1, 3]], [['b', 'a', 2], [3, 1]], [['b', 'a', 3], [1, 2]], [['b', 'a', 3], [2, 1]]]
      

      【讨论】:

        【解决方案5】:

        此时,这个问题已经提出了 5 年,但我找到了一个比给出的答案稍微好一点的答案(这很有帮助)。这个答案解释了更大的二维数组。

        from itertools import permutations, chain
        from pprint import pprint
        d = np.array([[1, 1], [0, 0]])
        pprint([np.array(i).reshape(d.shape).tolist() for i in set(permutations(chain.from_iterable(d)))])
        

        输出:

        [[[1, 1], [0, 2], [2, 0]],
         [[1, 0], [1, 0], [2, 2]],
         [[1, 0], [0, 2], [1, 2]],
         [[1, 2], [1, 0], [2, 0]],
         [[1, 0], [1, 2], [0, 2]],
         [[2, 1], [0, 2], [1, 0]],
         [[2, 1], [0, 0], [2, 1]],
         [[1, 2], [0, 2], [1, 0]],
         [[2, 0], [0, 2], [1, 1]],
         [[2, 1], [0, 1], [0, 2]],
         [[1, 1], [2, 0], [0, 2]],
         [[2, 0], [1, 0], [1, 2]],
         [[1, 0], [2, 2], [0, 1]],
         [[1, 2], [0, 1], [0, 2]],
         [[0, 2], [2, 0], [1, 1]],
         ...
        

        【讨论】:

          猜你喜欢
          • 2012-03-14
          • 1970-01-01
          • 1970-01-01
          • 2015-12-23
          • 1970-01-01
          • 1970-01-01
          • 2018-01-08
          • 2017-03-27
          • 1970-01-01
          相关资源
          最近更新 更多