![](/img/trans.png)
[英]How to restrict number of elements in list while doing itertools.combinations?
[英]Get certain number of elements from Itertools.combinations
我需要將迭代器中的元素總數拆分為 3 個部分: tot= itertools.combinations(dict1.keys(), 2)
。
dict1 的大小 = 285056 可能的總組合 = 400 億
我的目標是以某種方式將這 400 億分成 135 億個元素的 3 個部分,每個元素在不同的處理器上並行處理。 目前我正在天真地迭代 400 億個 pickle 文件,當我達到 135 億個時效率不高,因為每個 135 億個 pickle 在磁盤上有 160gb(加載到內存中時更大)
那么有沒有什么辦法可以在一個代碼中迭代第 400 億到第 135 億個元素,然后從代碼 2 中的第 136 個元素開始,依此類推,而無需像我那樣進行迭代。 下面的代碼我用來從可迭代的組合中獲取一定數量的元素。
def grouper(n, iterable):
it = iter(iterable)
while True:
chunk = tuple(itertools.islice(it, n))
if not chunk:
return
yield chunk
for first_chunk in grouper(1350000000,tot ):
使用itertools
創建這種拆分很容易。 給定一組元素,我們可以測試生成的組合的第一部分是否屬於機器 i 的計算。
在下面的代碼中,我展示了一個粗略的解決方案,for 循環中的代碼旨在拆分為 3 台機器。 機器i將運行組合的第一個元素的第 i 個鍵段的代碼,並結合第二個元素的完整集。
應該在計算cnt2
的行中處理組合。 將其替換為您想要處理組合的那種 for 循環。
與生成和存儲所有組合相比,此解決方案不存儲任何組合,但會(內部)生成所有組合。 但是朋友之間有幾十億的組合是什么?
import itertools
def is_not_for_machine(i, t):
""" t is in the set if first element
in my_set_prefix[i] for machine i """
if my_set_prefix[i][0] <= t[0] < my_set_prefix[i][1]:
return False
return True
my_set_prefix = []
for i in range(3):
my_set_prefix.append((len(my_keys)*i//3, len(my_keys)*(i+1)//3))
print(f"== partition: {my_set_prefix}")
my_keys = range(12)
all = itertools.combinations(my_keys, 2)
cnt = len([_ for _ in all])
print(f"== total set size {cnt}")
for i in range(3):
all = itertools.combinations(my_keys, 2)
cnt2 = len([_ for _ in itertools.filterfalse(lambda t: is_not_for_machine(i, t), all)])
print(f"== set size for prefix {my_set_prefix[i]}: {cnt2}")
output 表明可能需要進行一些負載平衡,因為此分區是“三角形降序”,第一個組合的計數最高。
== partition: [(0, 4), (4, 8), (8, 12)]
== total set size 66
== set size for prefix (0, 4): 38
== set size for prefix (4, 8): 22
== set size for prefix (8, 12): 6
為什么不直接使用 math.comb 命令來獲取組合的數量呢?
只是 go 那里的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.