python - 使用 pandas read_csv 时出现内存错误

标签 python windows pandas

我正在尝试做一些相当简单的事情,将一个大的 csv 文件读入 pandas 数据帧。

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

代码要么因 MemoryError 而失败,要么永远不会完成。

任务管理器中的内存使用停止在 506 Mb 并且在 5 分钟没有变化并且进程中没有 CPU 事件后,我停止了它。

我使用的是 Pandas 版本 0.11.0。

我知道文件解析器曾经存在内存问题,但根据 http://wesmckinney.com/blog/?p=543 这应该已经解决了。

我要读取的文件是 366 Mb,如果我将文件缩减为较短的文件 (25 Mb),上面的代码就可以工作。

还发生了一个弹出窗口,告诉我它无法写入地址 0x1e0baf93...

堆栈跟踪:

Traceback (most recent call last):
  File "F:\QA ALM\Python\new WIM data\new WIM data\new_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 216, in _read
    return parser.read()
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

一些背景知识 - 我试图让人们相信 Python 可以做与 R 相同的事情。为此,我正在尝试复制一个可以做到的 R 脚本

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

R 不仅可以很好地读取上述文件,它甚至可以在 for 循环中读取其中的几个文件(然后对数据进行一些处理)。如果 Python 确实对这种大小的文件有问题,我可能会打一场失败的战斗......

最佳答案

Windows 内存限制

在 Windows 中使用 32 位版本时,python 经常发生内存错误。这是因为 32 位进程 only gets 2GB of memory to play with默认情况下。

降低内存使用率的技巧

如果您不在 Windows 中使用 32 位 python,但希望在读取 csv 文件时提高内存效率,那么有一个技巧。

pandas.read_csv function接受一个名为 dtype 的选项。这让 pandas 知道您的 csv 数据中存在哪些类型。

这是如何工作的

默认情况下,pandas 会尝试猜测您的 csv 文件有哪些 dtypes。这是一个非常繁重的操作,因为在确定 dtype 时,它​​必须将所有原始数据作为对象(字符串)保存在内存中。

示例

假设您的 csv 如下所示:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01

这个例子读入内存当然没问题,但只是一个例子。

如果 pandas 读取上述 csv 文件 没有任何 dtype 选项,则年龄将作为字符串存储在内存中,直到 pandas 读取 csv 文件的足够行来做出合格的猜测。

我认为 pandas 的默认设置是在猜测 dtype 之前读取 1,000,000 行。

解决方案

通过将 dtype={'age':int} 指定为 .read_csv() 的一个选项,pandas 将知道年龄应该被解释为一个数字。这样可以节省大量内存。

数据损坏问题

但是,如果您的 csv 文件会损坏,如下所示:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01
Dennis, 40+, None-Ur-Bz

然后指定 dtype={'age':int} 将破坏 .read_csv() 命令,因为它不能强制转换 "40+" 到 int。因此,请仔细清理您的数据!

在这里您可以看到当 float 保存为字符串时,pandas 数据帧的内存使用量是如何高得多的:

自己试试

df = pd.DataFrame(pd.np.random.choice(['1.0', '0.6666667', '150000.1'],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 224544 (~224 MB)

df = pd.DataFrame(pd.np.random.choice([1.0, 0.6666667, 150000.1],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 79560 (~79 MB)

关于python - 使用 pandas read_csv 时出现内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17557074/

相关文章:

python - Selenium 文件错误,我无法正确导入它们

Python 对字典中回调的引用

python - 如何在 python 中迭代给定日期的几个小时?

python - 如果另一列数据在列表中, Pandas 会更改一列数据

python - 在 python 中处理 tiff 文件

python - 在 Scrapy 中使用 CSS 和 Xpath 选择器

java - Netbeans 不断重启

windows - 在 windows 上计算文件夹的校验和并在 linux 上验证

java - 如何在 Windows 的 shell 脚本中配置 JAVA_HOME

python - Python中有没有增加时间戳的函数