【问题标题】:Python MemoryError or ValueError in np.loadtxt and iter_loadtxtnp.loadtxt 和 iter_loadtxt 中的 Python MemoryError 或 ValueError
【发布时间】:2014-12-20 21:40:26
【问题描述】:

我的出发点是 NumPy 的函数 loadtxt 有问题:

X = np.loadtxt(filename, delimiter=",")

np.loadtxt(..) 中给出了MemoryError。我用谷歌搜索并来到this question on StackOverflow。这给出了以下解决方案:

def iter_loadtxt(filename, delimiter=',', skiprows=0, dtype=float):
    def iter_func():
        with open(filename, 'r') as infile:
            for _ in range(skiprows):
                next(infile)
            for line in infile:
                line = line.rstrip().split(delimiter)
                for item in line:
                    yield dtype(item)
        iter_loadtxt.rowlength = len(line)

    data = np.fromiter(iter_func(), dtype=dtype)
    data = data.reshape((-1, iter_loadtxt.rowlength))
    return data

data = iter_loadtxt('your_file.ext')

所以我尝试了,但随后遇到以下错误消息:

> data = data.reshape((-1, iter_loadtext.rowlength))
> ValueError: total size of new array must be unchanged

然后我尝试将行数和最大列数添加到代码中,代码片段在这里,我部分得到了from another question,部分是我自己写的:

num_rows = 0
max_cols = 0
with open(filename, 'r') as infile:
    for line in infile:
        num_rows += 1
        tmp = line.split(",")
        if len(tmp) > max_cols:
            max_cols = len(tmp)

def iter_func():
    #didn't change

data = np.fromiter(iter_func(), dtype=dtype, count=num_rows)
data = data.reshape((num_rows, max_cols))

但这仍然给出了相同的错误消息,尽管我认为它应该已经解决了。另一方面,我不确定我是否以正确的方式调用data.reshape(..)

我评论了调用date.reshape(..) 以查看发生了什么的规则。这给出了这个错误信息:

> ValueError: need more than 1 value to unpack

这发生在使用X 完成某些操作的第一点,即问题所在的变量。

我知道这段代码可以处理我得到的输入文件,因为我看到它与它们一起使用。但我找不到为什么我不能解决这个问题。我的推理是这样的,因为我使用的是 32 位 Python 版本(在 64 位 Windows 机器上),内存出现问题而在其他计算机上不会发生。但我不确定。有关信息:我有 8GB 的​​ RAM 用于 1.2GB 的文件,但根据任务管理器,我的 RAM 未满。

我想要解决的是,我正在使用需要读取和解析给定文件的开源代码,就像np.loadtxt(filename, delimiter=",") 一样,但是在我的记忆中。我知道代码最初在 MacOsx 和 Linux 中工作,更准确地说:“MacOsx 10.9.2 and Linux (version 2.6.18-194.26.1.el5 (brewbuilder@norob.fnal.gov) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)) 1 SMP Tue Nov 9 12:46:16 EST 2010)。"

我不太在乎时间。我的文件包含 +-200.000 行,其中每行有 100 或 1000 个(取决于输入文件:一个始终为 100,一个始终为 1000)项,其中一项是浮点数,其中 3 位小数是否被否定,并且它们由, 和一个空格分隔。 F.e.:[..] 0.194, -0.007, 0.004, 0.243, [..],以及 100 或 100 个您看到 4 的项目,对于 +-200.000 行。

我使用的是 Python 2.7,因为开源代码需要它。

你们中的任何人都有解决方案吗?提前致谢。

【问题讨论】:

  • 您以正确的方式使用reshape。但是count=num_rows 是一个错误,会导致第二个代码出错。它应该是值的总数,所以count=num_rows*num_cols
  • 谢谢,成功了。但现在我在X = np.asfortranarray(X, [..]) 中得到了一个 MemoryError。 dtype 与我在iter_loadtxt 中使用的相同。它停在 +-700mb 的内存上,这不是我的机器可以给进程的 RAM 的末尾...
  • 好的。我认为下一个问题是您的 contiguous 内存地址用完了,但老实说,我不太确定在 64 位操作系统上如何使用 32 位进程。 . 无论如何,最简单的解决方法是获得 64 位 Python。也许'WinPython' 很好,因为它是 64 位的并且是可移植的。
  • 问题是 NumPy 只适用于 Windows 上的 32 位 Python 安装,所以我真的不能使用 64 位 Python 版本。否则我会立即安装它。我假设没有其他解决方案可以用完连续的内存地址?如果没有,我会考虑另一种解决方案。
  • 据我所知 64 位 Numpy 在 Windows 上运行良好,但如果我错了请纠正我:)

标签: python memory file-io numpy


【解决方案1】:

在 Windows 上,32 位进程最多只能获得 2GB(或 GiB?)内存,而 numpy.loadtxt 因占用大量内存而臭名昭著,这就解释了为什么第一种方法不起作用。

您似乎面临的第二个问题是您正在测试的特定文件缺少数据,即并非所有行都具有相同数量的值。这很容易检查,例如:

import numpy as np

numbers_per_line = []
with open(filename) as infile:
    for line in infile:
        numbers_per_line.append(line.count(delimiter) + 1)

# Check where there might be problems
numbers_per_line = np.array(numbers_per_line)
expected_number = 100
print np.where(numbers_per_line != expected_number)

【讨论】:

  • 我不知道第一件事,谢谢。我使用了你的代码,它说每一行都有预期的数字,所以这不是问题,不幸的是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 2011-04-28
  • 2012-12-15
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
相关资源
最近更新 更多