使用熊猫read_csv时出现内存错误


79

我正在尝试做相当简单的事情,将一个大的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确实对这种大小的文件存在问题,那么我可能正在与一场艰苦的战斗...


1
毫无疑问,大熊猫应该不会遇到这种大小的csvs问题。您可以在线发布此文件吗?
安迪·海登

1
您也可以尝试传递nrows=something smallread_csv以确保不是引起问题的文件大小,正如安迪所说,情况并非如此。
TomAugspurger

1
这可能与“ Visual Studio,使用Anaconda和PTVS”有关……也许也可以在常规python中尝试
Andy Hayden

3
我发现以下解决此问题的方法:将csv作为块读取csv_chunks = pandas.read_csv(filepath, sep = DELIMITER,skiprows = 1, chunksize = 10000),然后将这些块连接起来df = pandas.concat(chunk for chunk in csv_chunks)。我仍然很想知道为什么不能一次阅读它,对我来说,这似乎是csv阅读器的问题。
安妮

11
如果有人仍然在关注这个问题,我会进行一些更新。我已经相信csv解析器很好(也非常快),但是在创建数据帧时存在某种内存问题。我相信这一点的原因:当我使用chunksize=1000hack读取csv,然后尝试将所有块连接到一个大数据帧中时,此时内存消耗memory尽,与大小相比,内存占用约为3-4倍原始文件。有谁知道为什么数据帧可能会崩溃?
安妮(Anne)

Answers:


32

Windows内存限制

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

降低内存使用量的技巧

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

pandas.read_csv功能采用所谓的选项dtype。这样一来,熊猫就能知道csv数据中存在哪些类型。

这如何运作

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

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

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

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

如果熊猫在不使用任何dtype选项的情况下读取上述csv文件,则年龄将作为字符串存储在内存中,直到熊猫已读取足够的csv文件行以做出合格的猜测为止。

我认为熊猫的默认设置是在猜测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)

我可以看到这如何加快读取数据的速度,但减少了内存?当然,不必为每个列存储多个字符串值来猜测数据类型吗?也就是说,除非您有成千上万的列,或者read_csv函数正在执行令人难以置信的时髦,否则如果内存使用量明显更高,我将感到非常惊讶。
汉尼斯·奥夫雷恩(HannesOvrén)2015年

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

1
嗯,考虑一下,我想确定“ 3”是浮点数还是整数可能是有问题的,除非您在某处也看到“ 2.5”。感谢您的解释。我对此一无所知。
汉尼斯·奥夫雷恩(HannesOvrén)2015年

这不是真的。使用dtype是,并且在内存中更昂贵,并且时间更慢。在read_csv中使用dtype测试了6次。平均数为:...内存编号类型:12,121,429.333333334 | dtype的内存:12,124,160.0 ...在经过13次测试的时间中,平均值为:... time no dtypes:2.0494697460761437 | dtypes的时间:2.100334332539485 ...使用过的:import os import psutil process = psutil.Process(os.getpid())print(process.memory_info()。rss)___数据行:来自三个分离的数据集的150万,列数为90%是对象类型。*显然float的大小小于字符串类型
nikolaosmparoutis

@nikolaos_mparoutis不确定这些结果如何。也许您想编写自己的答案,因为很难遵循注释中的代码和注释。我的回答很老,也许有些改变。
firelynx

6

通过简单地读取大约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 64位


7
这是违反直觉的,low_memory=False应该使用更少的内存
。– guillefix

2

我在Linux机器上使用了Pandas,并且遇到了很多内存泄漏问题,这些问题只有在从github上将Pandas克隆到最新版本后,才能解决。


1

当我在虚拟机中运行时,或者在内存受到严格限制的其他地方,我也遇到了此问题。它与pandas或numpy或csv没有关系,但是如果您尝试使用更多的内存(因为不仅要在python中使用),就总是会发生这种情况。

您拥有的唯一机会就是您已经尝试过的方法,尝试将大事物切成小块,放入内存中。

如果您曾经问​​自己MapReduce的全部功能,您会自己发现... MapReduce会尝试将块分配到许多机器上,您将尝试在一个机器上一个接另一个地处理这些块。

您发现的块文件连接可能确实是一个问题,也许此操作中需要一些副本...但是最后,这可能会节省您的当前情况,但是如果您的csv变大了一点你可能会再次撞到那堵墙...

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

您可以尝试以下几种方法:

  • 不要一次加载所有数据,而是分段
  • 据我所知,hdf5能够自动执行这些块,并且仅加载程序当前正在处理的部分
  • 查看类型是否正确,字符串“ 0.111111”比浮点数需要更多的内存
  • 您实际上需要什么,如果地址是字符串,则可能不需要它进行数值分析...
  • 数据库只能帮助访问和加载您实际需要的部分(例如,仅1%的活动用户)

1

Pandas 0.12.0和NumPy 1.8.0没有错误。

我已经设法创建一个大的DataFrame并将其保存到一个csv文件,然后成功读取它。请在此处查看示例。该文件的大小为554 Mb(它甚至适用于1.1 Gb文件,花费了更长的时间才能生成30秒的1.1 Gb文件使用频率)。虽然我有4Gb的可用RAM。

我的建议是尝试更新Pandas。可能有用的另一件事是尝试从命令行运行脚本,因为对于R,您没有使用Visual Studio(这已经在问题的注释中建议了),因此它具有更多可用资源。


1

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

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")

0

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

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


-1

尽管这不是一个解决方法,但它只是一个修复程序,我尝试将CS​​V转换为JSON(应该是微不足道的)并改用read_json方法-我一直在Pandas中编写和读取可观的JSON /数据帧(100兆字节)方式没有任何问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.