使用pandas read_csv时出现内存错误

时间:2013-07-09 19:57:50

标签: python windows pandas

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

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

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

任务管理器中的Mem使用停止在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对那个大小的文件有问题,我可能正在打一场失败的战斗......

8 个答案:

答案 0 :(得分:29)

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在没有任何dtype选项的情况下阅读上述csv文件,则年龄将作为字符串存储在内存中,直到pandas读取了足够的csv文件行以进行合格猜测。 / p>

我认为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

然后指定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)

答案 1 :(得分:3)

我有一个相同的内存问题,只需简单读取大约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

Spyder 3.2.3 Python 2.7.13 64bits

答案 2 :(得分:2)

Pandas 0.12.0和NumPy 1.8.0没有错误。

我已设法创建一个大的DataFrame并将其保存到csv文件,然后成功读取它。请参阅示例here。该文件的大小为554 Mb(它甚至适用于1.1 Gb文件,耗时更长,生成1.1Gb文件使用频率为30秒)。虽然我有4Gb的RAM可用。

我的建议是尝试更新Pandas。其他可能有用的事情是尝试从命令行运行脚本,因为对于R你没有使用Visual Studio(这已在你的问题的评论中提出),因此它有更多的资源可用。

答案 3 :(得分:2)

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

答案 4 :(得分:1)

当我在虚拟机中运行时,或者在内存严格限制的其他地方,我也遇到过这个问题。它与pandas或numpy或csv无关,但如果您尝试使用更多内存,则会发生这种情况,即使只是在python中也是如此。

你唯一的机会就是你已经尝试过的东西,试着把大东西变成适合记忆的小块。

如果你曾经问过自己MapReduce是什么,你自己发现...... MapReduce会尝试在很多机器上分发块,你会尝试在一台机器上一个接一个地处理chunke。

你发现块文件的串联可能确实是一个问题,也许这个操作需要一些副本......但最后这可能会让你在目前的情况下保存,但如果你的csv得到了你可能会再次撞到那堵墙......

也可能是,大熊猫是如此聪明,以至于它实际上只会将单个数据块加载到内存中,如果你对它做一些事情,比如连接到一个大df?

你可以尝试几件事:

  • 不要一次加载所有数据,而是分成几部分
  • 据我所知,hdf5能够自动执行这些块,只加载程序当前工作的部分
  • 查看类型是否正常,字符串&#39; 0.111111&#39;需要比浮动更多的内存
  • 实际上你需要什么,如果地址是一个字符串,你可能不需要它进行数值分析......
  • 数据库可以帮助只访问和加载您实际需要的部分(例如,只有1%的活跃用户)

答案 5 :(得分:0)

虽然这是一个解决方法而不是修复,但我尝试将该CSV转换为JSON(应该是微不足道的)并使用read_json方法 - 我一直在编写和阅读大量的JSON /数据帧(Pandas的100s)这样没有任何问题。

答案 6 :(得分:0)

我在读取大型CSV文件时尝试过chunksize

reader = pd.read_csv(filePath,chunksize=1000000,low_memory=False,header=0)

现在已读取列表。我们可以迭代reader并将其写入/追加到新的CSV或执行任何操作

for chunk in reader:
    print(newChunk.columns)
    print("Chunk -> File process")
    with open(destination, 'a') as f:
        newChunk.to_csv(f, header=False,sep='\t',index=False)
        print("Chunk appended to the file")

答案 7 :(得分:0)

添加以下内容: 评分= pd.read_csv(..., low_memory = False,memory_map = True

我对这两个记忆: #319.082.496 没有这两个: #349.110.272