使用 numpy 保存列表时内存不足

Posted

技术标签:

【中文标题】使用 numpy 保存列表时内存不足【英文标题】:Run out of memory when saving list with numpy 【发布时间】:2017-12-17 17:38:15 【问题描述】:

我有一个相当大的列表,代表搜狗文本分类数据集中的标记。我可以处理 450 000 的整个训练集,剩下 12 gigs 的 ram,但是当我在列表列表中调用 numpy.save() 时,内存使用量似乎翻了一番,而且我的内存用完了。

这是为什么? numpy.save 是否在保存之前转换列表但保留列表从而使用更多内存?

是否有另一种方法可以保存此列表列表,即酸洗?从 allow pickle 参数来看,我相信 numpy save 使用 pickle 协议:https://docs.scipy.org/doc/numpy/reference/generated/numpy.save.html

print "Collecting Raw Documents, tokenize, and remove stop words"
df = pd.read_pickle(path + dataSetName + "Train")
frequency = defaultdict(int)

gen_docs = []
totalArts = len(df)
for artNum in range(totalArts):
    if artNum % 2500 == 0:
        print "Gen Docs Creation on " + str(artNum) + " of " + str(totalArts)
    bodyText = df.loc[artNum,"fullContent"]
    bodyText = re.sub('<[^<]+?>', '', str(bodyText))
    bodyText = re.sub(pun, " ", str(bodyText))
    tmpDoc = []
    for w in word_tokenize(bodyText):
        w = w.lower().decode("utf-8", errors="ignore")
        #if w not in STOPWORDS and len(w) > 1:
        if len(w) > 1:
            #w = wordnet_lemmatizer.lemmatize(w)
            w = re.sub(num, "number", w)
            tmpDoc.append(w)
            frequency[w] += 1
    gen_docs.append(tmpDoc)
print len(gen_docs)

del df
print "Saving unfiltered gen"
dataSetName = path + dataSetName
np.save("%s_lemmaWords_noStop_subbedNums.npy" % dataSetName, gen_docs)

【问题讨论】:

这些“令牌”是什么?数值数据?还是更复杂的对象? 字符串,每个都是一个字 为什么要使用 numpy 来保存列表列表?这没有任何意义,如果它首先尝试从中创建一个数组,我不会感到惊讶。 您应该使用pickle 或 JSON 甚至将其设为 CSV 我确实试过 allow_pickle=False: raise ValueError("Object arrays cannot be saved when " ValueError: Object arrays cannot be saved when allow_pickle=False 【参考方案1】:

np.save 首先尝试将输入转换为数组。毕竟它是为了保存 numpy 数组而设计的。

如果结果数组是具有数字或字符串值 (dtype) 的多维数组,它会保存一些基本维度信息,以及数组数据缓冲区的内存副本。

但如果数组包含其他对象(例如 dtype 对象),则它会腌制这些对象,并保存生成的字符串。

我会试试的

arr = np.array(gen_docs)

这会产生内存错误吗?

如果不是,它的shapedtype 是什么?

如果tmpDoc(子列表)的长度不同,arr 将是一个具有 object dtype 的一维数组 - 这些对象是 tmpDoc 列表。

只有当所有tmpDoc 的长度相同时,它才会生成一个二维数组。即使这样,dtype 也将取决于元素,无论是数字、字符串还是其他对象。

我可能会补充一点,数组是使用save 协议腌制的。

【讨论】:

我已经尝试过: gen_docs = np.array(gen_docs) 然后保存它,同样的问题。 tmpDoc 子列表的长度确实不同。代码再次运行后,我将使用 shape 和 dtype 对其进行更新。 如果您无法将整个列表转换为数组,则将其中的一部分转换为:np.rray(gen_docs[:100]) 可能仍然有用。关于 shape 和 dtype 的相同问题也适用。 用 2500 个文档运行它只是为了检查形状和 dtype 这就是我得到的:(2500,) object 所以它是那些tmpDoc 列表的一维数组。尝试使用 numpy 保存它并没有真正的好处。

以上是关于使用 numpy 保存列表时内存不足的主要内容,如果未能解决你的问题,请参考以下文章

大型 CSV 文件 (numpy) 上的 Python 内存不足

Python:在主内存不足时引发异常[重复]

为啥使用JAVA的时候老显示内存不足?

“内存不足,现在保存文件。”打开word 2003文档时出错

Numpy - 数组array的构造

运行时错误:CUDA 在训练结束时内存不足并且不保存模型;火炬