2014-01-08 23 views
2

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

我迄今所做的是将数据导入到变量“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文件从磁盘导入到内存中的变量“C”来有效地减少数据。

任何帮助将不胜感激。

干杯, 吉姆

PS 的另一种方法,我已经与用途“的fread”打转转,但它encouters同样的问题:

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 

回答

2

我相信textscan是必经之路去,但是你可能需要采取中间步骤。这里是我会做什么,假设你可以很容易地在一次读N线:与textscan(fileID,formatSpec,N)

  • 样品从这些线路

    1. 阅读在N行,把结果存储(文件或变量)和下降,其余
    2. 只要有行留下继续执行步骤1
    3. 可选的,取决于你的存储方法:所有存储的结果合并成一个大样本

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

  • 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的作品就好了