使用pandas read_csv时出现内存错误

Ann*_*nne 78 python windows pandas

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

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)
Run Code Online (Sandbox Code Playgroud)

代码要么失败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 . . .
Run Code Online (Sandbox Code Playgroud)

一点背景 - 我试图说服人们Python可以像R一样.为此我试图复制一个R脚本

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

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

fir*_*ynx 30

Windows内存限制

在Windows中使用32位版本时,python会发生很多内存错误.这是因为32位进程默认只能获得2GB的内存.

降低内存使用率的技巧

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

pandas.read_csv功能采用所谓的选项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
Run Code Online (Sandbox Code Playgroud)

这个例子当然没有读入内存的问题,但它只是一个例子.

如果pandas在没有任何dtype选项的情况下读取上面的csv文件,则年龄将作为字符串存储在内存中,直到pandas读取了足够的csv文件行以进行合格猜测.

我认为pandas中的默认值是在猜测dtype之前读取1,000,000行.

通过指定dtype={'age':int}作为.read_csv()遗嘱的选项,让大熊猫知道年龄应该被解释为数字.这可以节省大量内存.

数据损坏的问题

但是,如果您的csv文件已损坏,请执行以下操作:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01
Dennis, 40+, None-Ur-Bz
Run Code Online (Sandbox Code Playgroud)

然后指定dtype={'age':int}将中断.read_csv()命令,因为它无法转换"40+"为int.因此,请仔细清理您的数据!

在这里,您可以看到当浮点数保存为字符串时,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)
Run Code Online (Sandbox Code Playgroud)

  • @HannesOvrén在读取大量数据之前无法猜测数据类型,否则您将不得不多次更改它,这会增加成本。我认为熊猫默认会先读取前一百万行,然后再进行猜测。通过将dtypes添加到csv加载中,我已经将基于熊猫的产品的内存配置降低了50倍。 (2认同)

moo*_*man 5

我在简单读取大小约为 1 GB(超过 550 万条记录)的制表符分隔文本文件时遇到了同样的内存问题,这解决了内存问题吗?

df = pd.read_csv(myfile,sep='\t') # didn't work, memory error
df = pd.read_csv(myfile,sep='\t',low_memory=False) # worked fine and in less than 30 seconds
Run Code Online (Sandbox Code Playgroud)

Spyder 3.2.3 Python 2.7.13 64 位

  • `low_memory=False` 应该使用更少的内存是违反直觉的。 (8认同)

mrk*_*afk -1

虽然这是一个解决方法,但并不是一个解决方案,我会尝试将 CSV 转换为 JSON(应该是微不足道的)并使用read_json方法代替 - 我一直在 Pandas 中编写和读取相当大的 JSON/数据帧(数百 MB)完全没有任何问题。