【问题标题】:Iterating through a generator of itertools.combinations object takes forever遍历 itertools.combinations 对象的生成器需要永远
【发布时间】:2020-12-21 05:12:03
【问题描述】:

编辑::
在 cmets 和 Kevin 在 python chat 上与 juanpa & fusion 进行所有这些讨论之后,我得出的结论是,iterating 通过generator 所花费的时间与iterating 通过任何其他对象所花费的时间相同,因为生成器本身会即时生成那些combinations。此外,融合方法对len(arr)1000(可能到5k)都非常有效 - 但它由于超时而终止,当然是在线法官 - 请注意,这不是因为试图获得min_variance_sub,但我还必须得到min_variance_sub 中所有可能对的sum of absolute differences)。我将接受 fusion 的方法作为这个问题的答案,因为它回答了这个问题。 但我还将为该问题陈述创建一个新问题(更像是QnA,我还将在其中回答future visitors 的问题 - 我从其他候选人的提交中得到答案,editorial 由问题设置者提供,以及问题制定者本人的代码-尽管我不了解他们使用的方法)。我将在创建它时链接到另一个问题 :)
它是 HERE

原来的问题从下面开始

我在数组上使用itertools.combinations,所以首先我尝试了类似

aList = [list(x) for x in list(cmb(arr, k))]

其中 cmb = itertools.combinations,arr 是列表,k 是 int。 这对于 len(arr) MemoryError。

根据 kevin 在 Python Chat 上的建议,我使用了generator,它在生成这样的组合时工作得非常快

aGen = (list(x) for x in cmb(arr, k))

但是遍历这个生成器对象太慢了。 我尝试了类似的东西

for p in aGen:
    continue

甚至这段代码似乎也需要很长时间。

Kevin 还建议了一个关于 kth combination 的答案,这很好,但就我而言,我实际上想测试所有可能的组合并选择带有 minimum variance 的组合。

那么检查数组(列表)的所有可能组合是否具有minimum variance 的内存有效方法是什么(准确地说,我只需要考虑恰好具有 k 的子数组元素数量)

感谢您的帮助。

【问题讨论】:

  • 这里的k是什么?几乎可以肯定,您只是在使用非常多的组合。
  • 注意,aGen = (list(x) for x in cmb(arr, k)) 不会生成组合,它会创建 一个生成器,它会在您对其进行迭代时动态生成组合。所以当然它非常快,它并没有真正做任何工作
  • 在当前情况下 len(arr) 是 50,k 是 8。是的,组合的数量肯定很多。
  • 50 选择 8 是 536,878,650。十亿次迭代。假设您在每次迭代中所做的工作需要 1 毫秒,那么它将需要 536878650 * 1e-3 / (60*60) == 149.13295833333333 小时才能完成。现在,也许您在每次迭代中所做的工作较少,但这让您很好地了解这可能需要多长时间。你对每个组合做了什么操作?
  • 实际上,naive-approach 可能会更好,statistics 包必须处理各种不同的数字类型,并且非常小心,因此开销很大。我不认为时间复杂度在任何情况下都会有所不同,但当然,这里的常数因素很重要

标签: python list generator combinations variance


【解决方案1】:

你可以先用n元素对列表进行排序,

然后沿排序列表使用长度为 k 的移动窗口。

并找出n-k+1 可能组合的最小方差。

最小值应该是所有组合中的最小值。

 
def myvar(arr):
    l = len(arr)
    m = sum(arr)/l
    return sum((i-m)**2 for i in arr)/l


input_list = [.......]

sorted_list = sorted(input_list)

variance = None
min_variance_sub = None
for i in range(len(sorted_list) - k + 1):
    sub = sorted_list[i:i+k]
    var = myvar(sub)
    if variance is None or var<variance:
        variance = var
        min_variance_sub=sub
print(min_variance_sub)

【讨论】:

  • 这是一种划分并行执行问题的方法吗?
  • @Pynchia 当然,您可以将sorted_list 拆分为与k 重叠的重叠块,然后使用multiprocessing 计算每个块的最小方差,然后结合结果并找到全局最小值.
  • @PSSolanki 在这种情况下,您可以编写自己的方差计算器函数。请参阅上面的编辑。
  • 可能的错字:myvar 的返回语句应该是 return sum((i-m)**2 for i in arr)/l 吗?
  • @PSSolanki 如何移至聊天室?我是新来的,所以我知道该怎么做。如果您可以发布您的输入示例,我很乐意提供帮助。
猜你喜欢
  • 2018-03-10
  • 1970-01-01
  • 2016-11-05
  • 2012-07-25
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多