永久加载CSV文件

时间:2018-10-31 20:16:21

标签: matlab ram

我正在尝试将4.0 GB的大型CSV文件加载到Matlab中。我有40GB的RAM。但是,该表似乎尚未完成加载。 (活动监视器显示RAM使用量迅速增加,达到38.64GB,此后停止。CPU仍在大量使用。) 根据苹果的强制退出菜单,matlab没有被卡住。 (我想这是缺少的“ Matlab没有响应”消息的信号。)

第一个问题:为什么它甚至占用那么多RAM?我已经读取了RAM副本。我可以在这方面做些什么吗?

第二个问题:我可以加快这个项目的速度吗?以某种方式拆分CSV?

第三个问题:我可以加快计算机速度吗?它只占用30%的CPU容量,这是永远的事...为什么不使用更多的CPU?通风孔并不疯狂,所以我想“这很令人寒心”。

编辑:上升到72.80,现在正在下降... 编辑:现在回到55.something

Activity Monitor

3 个答案:

答案 0 :(得分:1)

Matlab您需要了解一些概念。

  1. 字符串存储为UINT16(某种程度上,我永远无法正确实现)。重要的是,这意味着每个字符都需要2个字节。如果将整个文件存储为长字符串,则将占用8 GB。
  2. 值(无论是数组还是标量)都与标头一起存储。这意味着存储一个字符串(从技术上讲是一个字符数组,字符串-用双引号而不是单引号引起的-可能有所不同)需要大约104个字节的标头。这意味着“测试”之类的内容大约需要108个字节!如果可以存储数字数组,则104字节的开销很小。如果您有一个标量单元格数组,则每个标量都占用112个字节(假设标量是8字节的两倍)。这可能有点令人困惑,但是最后这意味着,如果您不仔细阅读CSV文件,则内存需求可能会爆炸。

那你该怎么办。表尽可能将列存储为数组。您可以尝试readtable,尽管我认为基础实现可能并不高效。

对于大文件,Matlab建议使用datastore函数。尽管可能会有点慢,但它可以解决您的内存问题。

另一个选择是将整个文件读入内存并进行自己的自定义处理。例如,假设您没有任何转义符(即实际上不是定界符的逗号),则可以使用以下命令找到所有相关的定界符:

%Find comma or newline
I = regexp(temp,',|\n')

这是提取各种列的示例。如上所述,这对于字符串(字符数组)具有较大的开销,但对数字有效。

%Fake data as an example, 3 columns with middle one numeric
temp = sprintf('asdf,1234,temp\nfred,324,chip\ncheese,12,you are always right');
I = regexp(temp,',|\n');
starts = [0 I];
ends = [I length(temp)+1];

n_columns = 3;
%extract column 2
c2 = arrayfun(@(x,y) str2double(temp(x+1:y-1)),starts(2:n_columns:end),ends(2:n_columns:end));

%extract column 1
c1 = arrayfun(@(x,y) temp(x+1:y-1),...
    starts(1:n_columns:end),ends(1:n_columns:end),'un',0);

根据您的用例,这可能有效,也可能无效。要将文件读入内存,可以使用fileread

答案 1 :(得分:0)

我认为MatLab本身对允许输入的数量有限制。如果版本足够高,我相信您可以在首选项中进行设置。

查看以下内容:http://www.mathworks.com/help/matlab/matlab_env/set-workspace-and-variable-preferences.html

答案 2 :(得分:0)

对问题(2)的回答:假设行数多于列数,将csv拆分起来非常简单...

bigfile= csvread(filename);
bigLen=length(bigfile);
size=unint64(bliglen/2)
csvwrite('first.csv', bigfile(1:size,:));
csvwrite('second.csv', bigfile(size:beglen,:));

或者甚至用几个文件来做;它可能不会使整体速度更快,但是可以让您在读取每个文件时观察该过程。