【问题标题】:Crashing RAM while appending arrays追加数组时 RAM 崩溃
【发布时间】:2015-11-17 00:07:52
【问题描述】:

我有一个包含 140 万个样本 x 32 个特征的数据集。

我想将每个样本转换为前 1000 个样本加上自身的串联数组。由于我没有前 1000 个样本的早期数据,因此我将其删除。 因此,每个样本在转换后具有 1001*32 个特征。 我使用下面的代码,但每次都会崩溃,即使在我的 12GB RAM 笔记本电脑上也是如此。我在这里做错了什么。我怎样才能使这个计算可行?

def take_previous_data(X_train,y):
    temp_train_data=X_train[1000:]
    temp_labels=y[1000:] 
    final_train_set=[]
    for index,row in enumerate(temp_train_data):
        actual_index=index+1000
        final_train_set.append(X_train[actual_index-1000:actual_index+1].flatten())
    return  np.array(final_train_set),temp_labels

注意:使用 Python 2.7

【问题讨论】:

  • 假设数据类型为float,1400000*1000*32*8/1024/1024/1024 = 333GB
  • crash 是描述问题的糟糕方式。尽可能提供错误消息和上下文(堆栈跟踪)。它有助于准确地知道问题发生在代码中的哪个位置。此外,如果问题似乎与大小有关,请告诉我们哪些数据大小有效。
  • @hpaulj 没有错误。 python程序超过了我100%的内存使用率,我的电脑死机了。

标签: python numpy scipy ram


【解决方案1】:

请记住,当您对数组进行切片时,它实际上会返回一个副本,所以这已经很昂贵了 X_train[1000:] y[1000:] 但最昂贵的部分肯定是这个:X_train[actual_index-1000:actual_index+1] 我不知道 X_train 的确切大小是多少但是您至少要复制 1000 个元素...,然后使用 flatten() 进行另一个复制

类似的东西会占用更少的内存,使用生成器每次迭代你只会在内存中拥有一个副本,而不是 len(X_train) - 1000 副本。

import numpy as np

def train_generator(X_train):
    for index in xrange(1000, len(X_train)):
        yield X_train[index-1000:index+1].flatten()

def take_previous_data(X_train, y):
    return  np.array(train_generator(X_train)), y[1000:]


take_previous_data(['a'*100000000] * 2000, ['b'*100000000] * 2000) # passes easy on my 8GB laptop :)

我不知道代码的目标是什么,但您也可以查看转换数组的 numpy 方法,这可能会更有效。

【讨论】:

  • 这样的切片是视图,而不是副本。 flatten 确实返回了一份副本(请参阅它的文档)。 x.flatx.ravel 尽可能使用视图。
  • 我确实检查了 flatten() 的文档。 numpy.ndarray.flatten ndarray.flatten(order='C') Return a copy of the array collapsed into one dimension. docs.scipy.org/doc/numpy/reference/generated/… 虽然我不知道切片,标准 python 会复制。
  • X_train的原始大小是1,400,000*32,转换后是1,400,000*32032,这才是真正的问题
  • @Maresh 它返回给我生成器对象。考虑一下我想要一个简单的 PCA,它不会超出我的记忆。我怎样才能做到这一点? clf=PCA(0.98,whiten=True) ; X_train=clf.fit_transform(X_train)
  • 嗯,恐怕我的回答与 numpy 数组无关,请检查:stackoverflow.com/questions/367565/… 你需要预设数组,然后你就会失去使用生成器的好处......我猜猜你应该看看稀疏矩阵docs.scipy.org/doc/scipy/reference/sparse.html,或者想办法进行部分计算,但这超出了我的知识范围。
【解决方案2】:

至少据我了解,您正在尝试将数据量增加 1001%,因此除非您使用的数据量小于 10-11MB,否则您最终将获得超过 12GB 的数据量。

我的建议是从文件中读取每个单独的功能集计算所需的位,然后将输出写入另一个文件。

使用文件来存储您不对其执行操作的数据应该可以解决您的内存问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2014-11-23
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多