我想從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,你會怎麼做? –