簡體   English   中英

內核在itertools.combinations命令后死亡

[英]Kernel dies after itertools.combinations command

我正在使用Python 3.5.2 | Anaconda 4.3.0(x86_64)| (默認值,2016年7月2日,17:52:12)[GCC 4.2.1兼容的Apple LLVM 4.2(clang-425.0.28)]

我必須運行以下命令

longList = list(combinations(range(2134), 3))

我知道這筆費用的長度約為16億美元。 當我運行它時,一段時間后,我收到消息“內核似乎已經死亡。它將自動重新啟動。”

使用3而不是2的相同命令運行沒有任何問題:

longList = list(combinations(range(2134), 2))

在這種情況下,我應該/應該怎么辦?

您可能內存不足。 快速計算:64位int或指針為8個字節大。 您有16億個組合,它們是元組。 每個元組包含三個整數。 這意味着您至少需要1.6E9 *(1 + 3)* 8B = 48GB內存。

但是,由於Python的內存模型,您將需要的次數更多:每個整數實際上是一個對象,因此我們需要1個機器字作為列表中的指針,並可能需要3或4個機器字作為對象本身(我如果您不確定詳細信息,請閱讀CPython源代碼了解實際的對象布局。 元組對象也將有開銷。 我假設每個對象的開銷為兩個字。 因此,我們必須增加額外的1.6E9 *(3 +1)* 2 * 8B = 95GB的額外開銷,總計約為143GB。

通過使用密集的numpy數組可以避免這種情況,因為它使用實數而不是對象。 這消除了整數和元組對象的所有開銷,因此我們將“僅”需要1.6E9 * 3 * 8B = 35GB。

我假設您沒有運行具有那么多內存的硬件。

您的combinations(..., 2)調用不是問題,因為它僅產生大約200萬個元組,其內存需求在兆字節范圍內(2.2E6 *(1 + 4 + 2 * 3)* 8B = 180MB)。 作為一個numpy數組,我們只需要2.2E6 * 2 * 8B = 33MB。

那么這里的解決方案是什么?

  • 從規模上講,諸如內存模型之類的底層細節對於Python也非常重要。
  • 使用numpy可以大幅度減少內存使用量,通常減少4倍。如果使用較小的類型,則更多(例如dtype='int16'將減少4倍。
  • 認真考慮是否需要急切地將combinations()轉換為列表,還是可以懶散地或以較小的塊使用迭代器

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM