我想从itertools.product
的结果构建一个numpy
数组。我的第一种方法是简单的:从itertools构建一个大的numpy数组产品
from itertools import product
import numpy as np
max_init = 6
init_values = range(1, max_init + 1)
repetitions = 12
result = np.array(list(product(init_values, repeat=repetitions)))
此代码可以很好地用于“小” repetitions
(如< = 4),但与“大”的值(> = 12)它完全猪存储器和崩溃。我认为构建这个列表就是吃所有RAM的东西,所以我搜索了如何直接使用数组。我发现Numpy equivalent of itertools.product和Using numpy to build an array of all combinations of two arrays。
所以,我测试了以下选择:
备选#1:
results = np.empty((max_init**repetitions, repetitions))
for i, row in enumerate(product(init_values, repeat=repetitions)):
result[:][i] = row
备选#2:
init_values_args = [init_values] * repetitions
results = np.array(np.meshgrid(*init_values_args)).T.reshape(-1, repetitions)
备选#3:
results = np.indices([sides] * num_dice).reshape(num_dice, -1).T + 1
#1是非常缓慢的。我没有足够的耐心让它完成(在2017年MacBook Pro上处理几分钟后)。 #2 and #3直到python解释器崩溃,像最初的方法一样,吃掉所有的内存。
之后,我认为我可以以不同的方式表达相同的信息,这对我仍然有用:一个dict
其中键将是所有可能的(排序的)组合,并且值将是这些组合。所以,我想:
替代#4:
from collections import Counter
def sorted_product(iterable, repeat=1):
for el in product(iterable, repeat=repeat):
yield tuple(sorted(el))
def count_product(repetitions=1, max_init=6):
init_values = range(1, max_init + 1)
sp = sorted_product(init_values, repeat=repetitions)
counted_sp = Counter(sp)
return np.array(list(counted_sp.values())), \
np.array(list(counted_sp.keys()))
cnt, values = count(repetitions=repetitions, max_init=max_init)
而行counted_sp = Counter(sp)
,从而触发得到发电机的所有值,也就是我的需要太慢(也花了好几分钟,我取消了)。
是否有另一种方式来生成相同的数据(或包含相同信息的不同数据结构),但没有提到的太慢或使用太多内存的缺点? PS:我测试了以上所有的实现对我的测试与一个小的repetitions
,并通过了所有的测试,所以他们给出一致的结果。
我希望编辑这个问题是扩展它的最好方法。否则,让我知道,我会在我应该的地方编辑帖子。
在阅读下面的前两个答案并思考它之后,我同意我从错误的角度接近问题。我不应该用“暴力”的方法来使用概率,而应该使用它。
我的意图是,稍后,对于每个组合: - 计算有多少个值低于阈值X. - 计算有多少值等于或超过阈值X并低于阈值Y. - 计算有多少值超过阈值Y. 并对具有相同计数的组合进行分组。
作为说明性实例: 如果我辊6下侧的12个骰子,什么是具有M个骰子具有值< 3,N骰子具有值> = 3和< 4,和P骰子具有值的概率> 5,所有可能的M,N和P组合?
所以,我认为我会在几天内完成这个问题,而我将采用这种新方法。感谢您的所有反馈和您的时间!
可能想看看这个:https://stackoverflow.com/a/11146645/4909087 –
为什么你想这样做?假设你可以成功创建np.array,你会怎么做? –