Python Numpy内存错误

时间:2017-01-01 11:40:49

标签: python arrays numpy

我试图比较两个MD5哈希列表并确定匹配项。其中一个列表包含大约34,000,000个哈希值,另一个列表包含多达1,000,000个哈希值。

使用Numpy我一直在尝试与标准python数组进行比较所花费的时间,性能差异令人印象深刻。我一直使用的实验哈希数据集只包含1,000,000,但是当我尝试模拟34,000,000的目标数据集时,python脚本返回以下错误:

process started - [2017-01-01 11:23:18]
Traceback (most recent call last):
File "compare_data.py", line 30, in <module>
compare_array_to_array()
File "compare_data.py", line 24, in compare_array_to_array
np_array_01 = read_sample_data_01_array()
File "compare_data.py", line 9, in read_sample_data_01_array
np_array_01 = np.array(sample_data_01)
MemoryError

我已经看过其他关于Numpy Memory Errors的帖子,但是我很难理解问题是如何解决的,所以我事先道歉可能之前已经提出过这个问题。

完整的脚本如下:

from datetime import datetime
import numpy as np

def read_sample_data_01_array():
    sample_data_01 = []
    with open("data_set_01.txt", "r") as fi: #34,000,000 hashes
        for line in fi:
            sample_data_01.append(line)
    np_array_01 = np.array(sample_data_01)
    return(np_array_01)


def read_sample_data_02_array():
    sample_data_02 = []
    with open("data_set_02.txt", "r") as fi: #1,000,000 hashes
        for line in fi:
            sample_data_02.append(line)
    np_array_02 = np.array(sample_data_02)
    return(np_array_02)


def compare_array_to_array():
    np_array_02 = read_sample_data_02_array()
    np_array_01 = read_sample_data_01_array()
    ct = np.sum(np_array_01 == np_array_02)
    print(ct)


print("process started - [{0}]".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))    
compare_array_to_array()
print("process completed - [{0}]".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

这个代码运行的当前工作站是32位,就像Python一样,说Ubuntu可以看到8GB的RAM,虽然我怀疑其中只有4个是可寻址的?目标工作站包含64GB RAM,是一个64位系统,但我想迎合较小的系统

下面是我试图比较的数据集中包含的字符串示例:

XDPUXSRCYCYTYEUPQMGXEDPHQTDOCLEK
FPNXWZTALSZULLWLPCMTGTAKIGMCAMFT
NKIOLIINPXBMUUOLYKWWBCIXCIVKWCPO
DPLIXJCFJOKLSZUSRPPBDBAADXEHEDZL
NGIMMXKXZHIQHTCXRPKGWYPUPJMAJAPQ

非常感谢

1 个答案:

答案 0 :(得分:0)

通过这个例行程序:

def read_sample_data_01_array():
    sample_data_01 = []
    with open("data_set_01.txt", "r") as fi: #34,000,000 hashes
        for line in fi:
            sample_data_01.append(line)
    np_array_01 = np.array(sample_data_01)
    return(np_array_01)

首先创建一个本机python列表,然后用它创建一个numpy数组。在某些时候,你需要的内存大约是最终所需内存的两倍,这可以解释你的内存不足。

您可以使用numpy.loadtxt直接读取文件,但我怀疑它需要相同的内存量,因为它会自动计算数据大小,所以这是我的解决方案:使用fromiter并指定数据类型为"<U32"所以numpy知道它每个单元最多分配32个字节(因为迭代过程不能预先知道最大大小,这也是它节省内存的原因):

def read_sample_data_array(filepath):
   with open(filepath) as f:
    array = np.fromiter((line.strip() for line in f),dtype="<U32")
   return array

(请注意生成器理解表达式(line.strip() for line in f),它不会像[line.strip() for line in f]那样分配内存。

然后:

np_array_02 = read_sample_data_array("data_set_02.txt")
np_array_01 = read_sample_data_array("data_set_01.txt")

然而,这仍然需要太多内存,所以让我提出一个非numpy替代方案,只使用base python:

with open("data_set_02.txt", "r") as fi: #1,000,000 hashes
    s = {line.strip() for line in fi}

with open("data_set_01.txt", "r") as fi: #34,000,000 hashes
    number_of_matches = sum(1 for line in fi if line.strip() in s)
  1. 阅读&#34; small&#34;数据集并将其放在set中以便快速查找
  2. 阅读&#34; big&#34;数据集逐行(所以没有内存消耗)和使用sum和条件生成器理解的计数匹配
  3. 即使大数据集更大,这应该可以做到并且相对快速。你不需要大数据集在内存中。