如何在处理数十亿条目的数组时提高 Python 中的内存使用率?

How to improve memory usage in Python while processing an array of billions of entries?

我正在构建一个脚本来处理包含数十亿个条目的数组。对于这个数组的每个元素,我需要将每个元素与数组中的所有元素相加。例如:

list = [0, 1, 2]
result = [0+0, 0+1, 0+2, 1+0, 1+1, 1+2, 2+0, 2+1, 2+2]
output -> [0, 1, 2, 1, 2, 3, 2, 3, 4]

我正在使用 numpy.ogrid() 创建这个包含数十亿个条目的数组(我认为它更快)。另外,我正在尝试使用 itertools.product() 来获取它的产品并能够对它们求和。 这是我的代码:

import numpy as np
from datetime import datetime
import itertools

startTime = datetime.now()
array = np.ogrid[150000000:3000000000]
print("Array creation took: ", datetime.now() - startTime)

for element in (list(itertools.product(array, array))):
    if(element[0]+ element[1] == 3756499519):
        print("Found: ", element[0])
        print("Found: ", element[1])
        break

print("Running took: ", datetime.now() - startTime)

当这个数组很小的时候,一切看起来都很棒。但是当我尝试使用当前大小 运行 时,zsh 正在终止进程,可能是因为内存不足 zsh: killed /usr/bin/python3。有什么办法可以提高内存使用率吗?我不知道,也许在处理后删除元素? 我正在使用 Macbook Air M1。

你可以尝试使用广播:

import numpy as np

# Minimal example:
x = np.array([0, 1, 2])
# Get the result
r = (x+x[:,None]).flatten()
# r = array([0, 1, 2, 1, 2, 3, 2, 3, 4])

但是,如果您只需要找到一对总和为特定数字的值,并且这些数字包含在 Z(整数集)的子集中,那么您只需求解方程即可:

x+y = desired_sum
y >= min(subset(Z))

list(itertools.product(...)) 害死你了。 Itertools 是惰性的,这意味着它不会创建当前未使用的数据结构。 List 通过强制迭代器采用列表格式打破了这一点。删除对 list() 的调用将使您能够改用迭代器,这将提高内存效率。

类似这样的东西将有效地使用 itertools 包:

for a, b in itertools.product(array, array):
    if(a + b == 3756499519):
        print("Found: ", a)
        print("Found: ", b)
    break