2

我有 .txt 格式的非常大的数据文件(通常为 30Gb 到 60Gb)。我想找到一种方法来自动抽取文件而不先将它们导入内存。我的 .txt 文件包含两列数据,这是一个示例文件: https ://www.dropbox.com/s/87s7qug8aaipj31/RTL5_57.txt

到目前为止,我所做的是将数据导入变量“C”,然后对数据进行下采样。这种方法的问题是变量“C”经常在程序更改为抽取之前填充 MATLAB 的内存容量:

function [] = textscan_EPS(N,D,fileEPS )
%fileEPS: .txt address
%N: number of lines to read
%D: Decimation factor

fid = fopen(fileEPS);
format = '%f\t%f';

C = textscan(fid, format, N, 'CollectOutput', true);% this variable exceeds memory capacity

d = downsample(C{1},D);  
plot(d);

fclose(fid);


end

我该如何修改这一行:

C = textscan(fid, format, N, 'CollectOutput', true);

因此,它通过将 .txt 文件的每隔一行或每 3 行等从磁盘导入到内存中的变量“C”,从而有效地抽取数据。

任何帮助将非常感激。

干杯,吉姆

PS我一直在玩的另一种方法使用“fread”,但它遇到了同样的问题:

function [d] = fread_EPS(N,D,fileEPS)
%N: number of lines to read
%D: decimation factor
%fileEPS: location of .txt fiel

%read in the data as characters
fid = fopen(fileEPS);
c = fread(fid,N*19,'*char');% EWach line of .txt has 19 characters

%Parse and read the data into floading point numbers 
f=sscanf(c,'%f');

%Reshape the data into a two column format
format long 
d=decimate((flipud(rot90(reshape(f,2,[])))),D); %reshape for 2 colum format, rotate 90, flip veritically,decimation factor
4

2 回答 2

2

我相信 textscan 是要走的路,但是您可能需要采取中间步骤。假设您一次可以轻松地阅读N行,我会这样做:

  1. 读入 N 行textscan(fileID,formatSpec,N)
  2. 从这些行中采样,存储结果(文件或变量)并删除其余部分
  3. 只要有剩余的行继续执行步骤 1
  4. 可选,取决于您的存储方法:将所有存储的结果合并到一个大样本中

应该可以每次只读取 1 行,然后决定是否要保留/丢弃它。虽然这应该消耗最少的内存,但我会尝试每次做几千次以获得合理的性能。

于 2014-01-08T14:53:14.633 回答
0

我最终根据 Dennis Jaheruddin 的建议编写了以下代码。它似乎适用于大型 .txt 文件(10GB 到 50Gb)。该代码还受到另一篇文章的启发: Memory map file in MATLAB?

Nlines = 1e3; % set numbe of lines to sample per cycle
sample_rate = (1/1.5e6); %data sample rate
DECE= 1;% decimation factor

start = 40;  %start of plot time
finish = 50; % end plot time

TIME = (0:sample_rate:sample_rate*((Nlines)-1));
format = '%f\t%f';
fid = fopen('C:\Users\James Archer\Desktop/RTL5_57.txt');

while(~feof(fid))

  C = textscan(fid, format, Nlines, 'CollectOutput', true);
  d = C{1};  % immediately clear C at this point you need the memory! 
  clearvars C ;
  TIME = ((TIME(end)+sample_rate):sample_rate:(sample_rate*(size(d,1)))+(TIME(end)));%shift Time along 
       if ((TIME(end)) > start) && ((TIME(end)) < finish); 
        plot((TIME(1:DECE:end)),(d(1:DECE:end,:)))%plot and decimate
       end
  hold on;
  clearvars d;
end

fclose(fid);

旧版本的 MATLAB 不能很好地处理此代码,出现以下消息:

Caught std::exception Exception message is: bad allocation

但是 MATLAB 2013 工作得很好

于 2014-01-13T16:19:34.053 回答