使用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