Python itertools.product

时间:2014-04-23 02:12:56

标签: python algorithm product itertools

我正在使用itertools包,并尝试在具有900个值的数组中创建1的2和3的所有可能组合,然后将其转换为30乘30的矩阵。我必须执行此操作的代码如下,并且工作正常。

for data in itertools.product([1,2,3], repeat=900):
    datalist=list(data)
    landarray=np.asarray(datalist).reshape(30, 30)

然而,我想要做的是让每个值(1,2和3)在900值数组中恰好出现300次。谢谢你的帮助!

3 个答案:

答案 0 :(得分:1)

只需对已经均匀分布的数组进行随机播放。

landarray = np.repeat([1,2,3], 300)
np.random.shuffle(landarray)
landarray = landarray.reshape((30,30))

我保证你不会重复landarray。也就是说:你需要制作一个[编辑] 10 ^ 213 landarray s,之后你有50/50的机会重复一次。

答案 1 :(得分:1)

您想生成np.repeat([1,2,3], 300) multiset的所有排列。 There is an algorithm that allows to generate the next permutation in O(1)。这是一个使用C++ std::next_permutation() function的简单算法,并按字典顺序打印排列:

#!/usr/bin/env python
"""Print all multiset permutations."""
import pyximport; pyximport.install() # $ pip install cython
from next_permutation import next_permutation

n = 3
multiset = bytearray('a'*n + 'b'*n + 'c'*n)
print(multiset)
while next_permutation(multiset):
    print(multiset)

其中next_permutation模块是在Cython中定义的Python的C扩展模块:

# cython: boundscheck=False
#file: next_permutation.pyx
cimport cpython.array # support array.array() on Python 2
from libcpp cimport bool

ctypedef unsigned char dtype_t
ctypedef dtype_t* Iter

cdef extern from "<algorithm>" namespace "std":
   bool cpp_next_permutation "std::next_permutation" (Iter first, Iter last)

def next_permutation(dtype_t[:] a not None):
    return cpp_next_permutation(&a[0], &a[0] + a.shape[0])

要构建它,请指定语言是C ++:

#file: next_permutation.pyxbld
from distutils.extension import Extension

def make_ext(modname, pyxfilename):
    return Extension(name=modname,
                     sources=[pyxfilename],
                     language="c++")

输出

aaabbbccc
aaabbcbcc
aaabbccbc
aaabbcccb
aaabcbbcc
aaabcbcbc
aaabcbccb
aaabccbbc
aaabccbcb
aaabcccbb
aaacbbbcc
aaacbbcbc
aaacbbccb
aaacbcbbc
aaacbcbcb
aaacbccbb
..snip..
cccaabbba
cccabaabb
cccababab
cccababba
cccabbaab
cccabbaba
cccabbbaa
cccbaaabb
cccbaabab
cccbaabba
cccbabaab
cccbababa
cccbabbaa
cccbbaaab
cccbbaaba
cccbbabaa
cccbbbaaa

next_permutation()函数接受任何支持缓冲区接口的函数,例如,它支持numpy数组:

import numpy as np
multiset = np.repeat(np.array([1,2,3], dtype=np.uint8), 3)

答案 2 :(得分:0)

(傻笑)您确实意识到您的代码生成了大约10 ** 430个矩阵,对吧?

即使是受限制的版本也会产生大约10 ** 426个矩阵。

你可能很长时间非常


编辑以获得规模感:

如果宇宙中的每个原子(大约10 ** 80)

每秒可以完成10亿次操作(10 ** 18)

如果你每次操作可以处理十亿个矩阵(10 ** 9)

如果你用十亿个宇宙(10 ** 9)

这样做了

我们宇宙当前年龄的十亿倍(约10 ** 26秒)

在十亿分之一十亿分之一十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿分之十亿完成了十亿分之一。

(我开始觉得像卡尔萨根; - )