2012-09-18 34 views
6

我在Linux Mint v12上运行Matlab R2011b和R版本2.13.1,并使用16 GB的RAM。Matlab中的textscan与R中的类似方法相比使用了过多的RAM

我有一个csv文件。前5行(和标题)是:

#RIC,Date[G],Time[G],GMT Offset,Type,Price,Volume 
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.68,1008 
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.68,1008 
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.66,300 
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.65,1000 
DAEG.OQ,07-JUL-2011,15:10:03.464,-4,Trade,1.65,3180 

该文件很大(约900MB)。

fid1 = fopen('/home/MyUserName/Temp/X.csv'); 
D = textscan(fid1, '%s%s%s%f%s%f%f', 'Delimiter', ',', 'HeaderLines', 1); 
fclose(fid1); 

虽然该文件是900MB,运行上面的代码时,系统监视器显示我的内存使用跳跃约2GB到10GB:鉴于字符和数字数据的组合,如下一个可以读取这个文件到MATLAB 。更糟糕的是,如果我尝试使用略大的csv文件(大约1.2 GB)执行同样的过程,我的RAM最大值为16GB,而Matlab从未设法完成数据读取(它只停留在“繁忙”模式)。

如果我想读取相同的文件到R,我可能会使用:

D <- read.csv("/home/MyUserName/Temp/X.csv", stringsAsFactors=FALSE) 

这需要一点比Matlab的长,但系统监视器显示我的内存使用率只有从2GB跳转到3.3GB(多给定原始文件大小更合理)。

我的问题有两个部分:

1)为什么是这样textscan内存在这种情况下猪?

2)是否有另一种方法可以用来在我的系统上将Matlab的这种类型的1.2GB csv文件取出而不会使内存溢出?

编辑:只是为了澄清,我很好奇,是否存在一个唯一的MATLAB的解决方案,即我没有兴趣在涉及使用不同语言的CSV文件分解成更小的解决方案大块(因为这是我已经做的)。对不起Trav1s,我应该从一开始就明确这一点。

回答

2

问题可能是那些“%s”字符串被读入到Matlab单元格中,这是低基数字符串的内存效率低下的数据结构。 Cellstrs对于这样的大型表格数据很糟糕。每个字符串最终都会存储在一个单独的基元char阵列中,每个阵列都有400字节的开销和碎片问题。你的900MB文件,看起来像1800万行;每行4个字符串,大约10-20 GB的单元格来存放这些字符串。啊。

你想要的是将这些字符串转换为紧凑的原始数据类型,因为它们正在进入,而不是将所有1800万行同时嗅探到庞大的单元格字符串。 datenums的日期和时间戳或您正在使用的任何数字表示形式,以及那些低基数字符串,或者作为2-d char数组或一些类似的分类变量。 (考虑到您的数据集大小,您可能希望这些字符串表示为查找表中的简单数字标识符,而不是字符。)

一旦你决定了你的压缩数据结构,有几种方法来加载它。你可以在纯Matlab中将读入分割为块:在循环中使用textscan()调用来读取1000行一段时间,解析并将该块中的单元格转换为其紧凑形式,将所有结果缓存起来,并在读取结束时将它们结合在一起。这将使峰值内存要求降低。

如果你要做很多这样的工作,而且性能很重要,你可能想下降到Java并编写你自己的解析器,它可以在字符串和日期进行转换之前进行转换,然后交付给他们回到Matlab作为更紧凑的数据类型。这并不困难,Java方法可以直接从Matlab调用,所以这可能只能用一种单独的语言来计算。

+0

谢谢安德鲁,这个问题看起来是一个很好的答案,但直到明天我才会有机会详细阅读(我在工作中)。对不起,延迟。 –

+0

安德鲁,好回答+1,谢谢。 –

0

对于2)你可以尝试使用csvread命令。我不知道性能如何,但至少它是一种选择。

另一种选择是使用像C或awk这样快得多的语言读取文件,然后将其分解为更小的文件。按顺序读取很多小文件比一个大文件占用更少的内存。

+0

嗨Trav1s,感谢您的建议。不幸的是,csvread(或者dlmread)仅适用于纯数字数据。所以他们在这种情况下不好(请参阅我的示例数据)。关于你的第二个建议,这实际上是我目前正在做的事情,尽管我使用R而不是C,因为R的数据导入功能并不是数据密集型的。 –

相关问题