【问题标题】:Processing a very very big data set in python - memory error在python中处理一个非常非常大的数据集 - 内存错误
【发布时间】:2013-01-11 04:00:08
【问题描述】:

我正在尝试使用 python 中的 csv 模块处理从 csv 文件中获取的数据。其中大约有 50 列和 401125 行。我使用以下代码块将该数据放入列表中

csv_file_object = csv.reader(open(r'some_path\Train.csv','rb'))
header = csv_file_object.next()
data = []
for row in csv_file_object:
    data.append(row)

我可以使用 len(data) 获取此列表的长度,它返回 401125。我什至可以通过调用列表索引来获取每个单独的记录。 但是当我尝试通过调用 np.size(data) 来获取列表的大小(我将 numpy 作为 np 导入)时,我得到了以下堆栈跟踪。

MemoryError Traceback(最近调用 最后)在() ----> 1 np.size(数据)

C:\Python27\lib\site-packages\numpy\core\fromnumeric.pyc 的大小(a, 轴)2198 返回 a.size 2199 除外 属性错误: -> 2200 return asarray(a).size 2201 else: 2202 try:

C:\Python27\lib\site-packages\numpy\core\numeric.pyc in asarray(a, dtype,顺序) 233 第234章 --> 235 返回数组(a,dtype,copy=False,order=order) 236 237 def asanyarray(a,dtype=None,order=None):

内存错误:

我什至不能使用列表索引将该列表分成多个部分,或者将该列表转换为 numpy 数组。它给出了同样的内存错误。

我该如何处理这种大数据样本。有没有其他方法可以处理像这样的大型数据集。

我在 windows 7 专业版中使用 ipython notebook。

【问题讨论】:

  • 您需要一次将所有行都保存在内存中吗?您是否只是对每一行进行一次性处理?另一种方法是制作一个 collections.NamedTuple 并将每一行转换为这些元组之一。它们占用的内存非常少。
  • 我内存中的行数越多越好。我会试试 NamedTuple 谢谢
  • 或者,如果您不需要 CSV 文件中的所有字段,则只选择您需要的字段,而不是将它们全部添加到 data?
  • 在我看来,您正在制作 Python list,而不是 numpy ndarray。因此,当您调用np.size 时,您的list 没有.size() 方法,并且np.size 回退到调用asarray,最终它(至少)制作了您的数据的另一完整副本记忆。如果 50x400k 是数字的话,它并没有那么大,如果是这样,我会使用 np.loadtxt 而不是通过 csv。如果您的数据主要不是数字,那么还有其他解决方案。

标签: python numpy python-2.7 data-analysis


【解决方案1】:

正如 @DSM 在 cmets 中所指出的,出现内存错误的原因是在列表上调用 np.size 会先将数据复制到数组中,然后再获取大小。

如果您不需要将其作为 numpy 数组使用,请不要调用 np.size。如果您确实想要类似 numpy 的索引选项等,您有几个选项。

您可以使用pandas,它用于处理大型非必要数字数据集,并且有一些很好的帮手和东西。

如果您不想这样做,您可以定义一个 numpy structure array 并首先逐行填充它,而不是制作一个列表并复制到其中。比如:

fields = [('name1', str), ('name2', float), ...]
data = np.zeros((num_rows,), dtype=fields)

csv_file_object = csv.reader(open(r'some_path\Train.csv','rb'))
header = csv_file_object.next()
for i, row in enumerate(csv_file_object):
    data[i] = row

您还可以基于header 定义fields,这样您就不必手动输入所有 50 个列名,但您必须为每个列指定数据类型。

【讨论】:

  • 大约有 50 个字段,要为它们定义特定的数据类型并不容易。所以我使用 'object' 作为 dtype 以便可以插入任何类型(在这种情况下是字段列表)。这种方法完成了工作。我也要试试熊猫。谢谢
猜你喜欢
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 2016-05-14
相关资源
最近更新 更多