使用pandasread_csv时出现内存错误

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

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

代码要么与MemoryError失败,要么永远不会结束。

任务pipe理器中的内存使用停在506 Mb,5分钟后没有任何变化,在这个过程中没有CPU活动,我停止了它。

我正在使用pandas版本0.11.0。

我知道,文件parsing器曾经是一个内存问题,但根据http://wesmckinney.com/blog/?p=543这应该已经修复。

我正在尝试阅读的文件是366 Mb,上面的代码如果将文件缩小到某个简短的值(25 Mb),就可以正常工作。

它也发生了,我得到一个popup式告诉我,它不能写地址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位进程默认只能获得2GB的内存 。

降低内存使用的技巧

如果你不是在windows下使用32位的python,但是在读取csv文件的时候想提高你的内存效率,那么有一个技巧。

pandas.read_csv函数带有一个名为dtype的选项。 这让大pandas知道什么types存在于您的CSV数据。

这是如何工作的

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

假设你的csv看起来像这样:

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

这个例子当然不会读入内存,但这只是一个例子。

如果大pandas没有任何dtype选项读取上面的csv文件,年龄将作为string存储在内存中,直到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。 所以仔细清理你的数据!

在这里你可以看到当一个string保持为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) 

当我在虚拟机中运行时,我也遇到了这个问题,或者在内存严格受限的情况下遇到了这个问题。 它和pandas或者numpy或者csv没有任何关系,但是如果你试图使用更多的内存的话,那么它总是会发生的。

你唯一的机会就是你已经尝试过的东西,试着把这件大事分成几个小小的东西,放在记忆里。

如果你问自己MapReduce是什么,你自己发现了…… MapReduce会试图在多台机器上分配块,你会试图在一台机器上一个接一个地处理这个块。

你发现大块文件的连接可能是一个问题的确,可能有一些需要在这个操作的副本…但最终这可能会节省你在目前的情况,但如果你的csv得到一点点大你可能会再次撞墙

也可以说,pandas是如此的聪明,它实际上只是把单个数据块加载到内存中,如果你使用它,像连接到一个大的DF?

你可以尝试几件事情:

  • 不要一次加载所有的数据,而是分成几部分
  • 据我所知,hdf5能够自动完成这些块,只加载你的程序当前工作的部分
  • 看看types是否正常,一个string“0.111111”比浮点数需要更多的内存
  • 实际上你需要什么,如果有地址作为string,你可能不需要它进行数值分析…
  • 数据库可以帮助访问和加载您实际需要的部分(例如,只有1%的活动用户)

Pandas 0.12.0和NumPy 1.8.0没有错误。

我已经设法创build一个大的DataFrame并将其保存到一个CSV文件,然后成功地读取它。 请看这里的例子。 该文件的大小是554 Mb(它甚至为1.1 Gb文件工作,花费更长的时间,生成1.1 Gb文件使用频率30秒)。 虽然我有4Gb的RAM可用。

我的build议是尝试更新pandas。 其他可能有用的东西是尝试从命令行运行你的脚本,因为对于R你没有使用Visual Studio(这已经在你的问题的意见中已经提出),因此它有更多的可用资源。

虽然这不是一个解决方法,但我试着将CSV转换为JSON(应该是微不足道的),并使用read_json方法,而不是 – 我一直在pandas这样没有任何问题。

我在我的Linux机器上使用pandas,并面临许多内存泄漏,只有从pandasgithub克隆后,pandas升级到最新版本才解决。

我有一个相同的内存问题,简单阅读大约1 GB(超过550万条logging)的制表符分隔的文本文件,这解决了内存问题

 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 

Spyder 3.2.3 Python 2.7.13 64bits