2013-10-24 11 views
6

içinde aşırı büyük ek yük Veriyle dolu büyük bir metin dosyası ayrıştırıyorum ve daha sonra yalnızca parçalarına kolayca yükleyebilmem için * .mat dosyası olarak diske kaydediyorum (daha fazla bilgi için bkz. here). dosyalarda okuma ve veri için here). Bunu yapmak için, her seferinde bir satırda okurum, çizgiyi ayrıştırın ve sonra dosyaya ekleyin. Sorun, dosyanın kendisinde bulunan veriden 3 büyüklük büyüklüğünün olmasıdır. İşte MATLAB .mat dosyasında

benim kod tam olmayan bir versiyonudur: 224515 hatlarının 13813 çözümlenen edildikten sonra çok uzun bir süre ve dosya boyutu çok büyük başlamıştı alarak olmuştu çünkü kod durdu
database = which('01_hit12.par'); 
[directory,filename,~] = fileparts(database); 
matObj = matfile(fullfile(directory,[filename '.mat']),'Writable',true); 

fidr = fopen(database); 
hitranTemp = fgetl(fidr); 
k = 1; 
while ischar(hitranTemp) 
    if abs(hitranTemp(1)) == 32; 
     hitranTemp(1) = '0'; 
    end 

    hitran = textscan(hitranTemp,'%2u%1u%12f%10f%10f%5f%5f%10f%4f%8f%15c%15c%15c%15c%6u%2u%2u%2u%2u%2u%2u%1c%7f%7f','delimiter','','whitespace',''); 

    matObj.moleculeNumber(1,k)  = uint8(hitran{1}); 
    matObj.isotopeologueNumber(1,k) = uint8(hitran{2}); 
    matObj.vacuumWavenumber(1,k) = hitran{3}; 
    matObj.lineIntensity(1,k)  = hitran{4}; 
    matObj.airWidth(1,k)   = single(hitran{6}); 
    matObj.selfWidth(1,k)   = single(hitran{7}); 
    matObj.lowStateE(1,k)   = single(hitran{8}); 
    matObj.tempDependWidth(1,k)  = single(hitran{9}); 
    matObj.pressureShift(1,k)  = single(hitran{10}); 

    if rem(k,1e4) == 0; 
     display(sprintf('line %u (%2.2f)',k,100*k/K)); 
    end 
    hitranTemp = fgetl(fidr); 
    k = k + 1; 
end 
fclose(fidr); 

ama son çıktı sadece 10k satırlarını temizlediğimi gösterdi. Ben bellek temizlenir ve ardından koştu:

S = whos('-file','01_hit12.mat'); 
fileBytes = sum([S.bytes]); 

T = dir(which('01_hit12.mat')); 
diskBytes = T.bytes; 

disp([fileBytes diskBytes diskBytes/fileBytes]) 

ve çıktı alın:

524894 896189009 1707,37141022759

ekstra 895664115 bayt kaplıyor oluyor? Yardım sayfasının biraz fazladan ek yük olması gerektiğini söylüyorum, ama neredeyse bir Gb betimleyici üstbilgisinin biraz fazla olduğunu hissediyorum!

Yeni bilgiler:
denedim öncesi tahsis belki MATLAB bir matris bir döngüde embiggened zaman yapar aynı şeyi yapıyordu düşünerek ve üzerindeki tüm matris için disk alanı bir parça ayırarak, dosyayı her yazmak, ve bu değil. Benim kısa onay komut döndüren bir dosyada uygun veri tipleri sonuçların sıfırlarla dosyayı Dolum:

8531570 71467 0,00837677004349727

Bu benim için daha mantıklı. Matlab dosyayı nadiren kaydediyor, dolayısıyla disk dosya boyutu bellekte tam matrisin boyutundan çok daha küçük. Bununla birlikte, değerleri gerçek verilerle değiştirmeye başladığında, daha önce olduğu gibi aynı davranışı alıyorum ve dosya boyutu tüm makul sınırların ötesine geçiyor.

Yeni yeni bilgi:
100 satır uzunluğundadır verilerin bir alt kümesi üzerinde bu çalıştı. Diske akış yapmak için, v7.3 formatında olması gerekir, bu yüzden alt kümeyi komutumdan geçirdim, belleğe yükledim ve ardından v7.0 formatı olarak yeniden yükledim.

v7.3:3800 8752 2,30
v7.0:3800 2561 0,67

şaşmamak v7.3 biçimi varsayılan değildir İşte sonuçlarıdır. Bu konuda bir şey bilen var mı? Bu bir hata veya özellik mi?

+0

İşletim sisteminiz diskte ne kadar alanın kullanıldığını söylüyor? – Daniel

+0

857,185Kb (Windows 7 64 bit, MATLAB 2013a 64 bit) – craigim

+0

Elbette benim için bir hata gibi görünüyor, ancak parçalara yazarak etrafta dolaşabilirsiniz. 10.000'lik parçalar için denedim ve dosya makul boyutlarda. – chappjc

cevap

2

Bu bana bir hata gibi görünüyor. Bir geçici çözüm, önceden ayrılmış diziler için parçalarına yazmaktır.diskte

... % your code plus pre-alloc first 
bs = 10000; 
while ischar(hitranTemp) 
    if abs(hitranTemp(1)) == 32; 
     hitranTemp(1) = '0'; 
    end 

    for ii = 1:bs, 
     hitran{ii} = textscan(hitranTemp,'%2u%1u%12f%10f%10f%5f%5f%10f%4f%8f%15c%15c%15c%15c%6u%2u%2u%2u%2u%2u%2 u%1c%7f%7f','delimiter','','whitespace',''); 
     hitranTemp = fgetl(fidr); 
     if hitranTemp==-1, bs=ii; break; end 
    end 

    % this part really ugly, sorry! trying to keep it compact... 
    matObj.moleculeNumber(1,k:k+bs-1)  = uint8(builtin('_paren',cellfun(@(c)c{1},hitran),1:bs)); 
    matObj.isotopeologueNumber(1,k:k+bs-1) = uint8(builtin('_paren',cellfun(@(c)c{2},hitran),1:bs)); 
    matObj.vacuumWavenumber(1,k:k+bs-1) = builtin('_paren',cellfun(@(c)c{3},hitran),1:bs); 
    matObj.lineIntensity(1,k:k+bs-1)  = builtin('_paren',cellfun(@(c)c{4},hitran),1:bs); 
    matObj.airWidth(1,k:k+bs-1)   = single(builtin('_paren',cellfun(@(c)c{5},hitran),1:bs)); 
    matObj.selfWidth(1,k:k+bs-1)   = single(builtin('_paren',cellfun(@(c)c{6},hitran),1:bs)); 
    matObj.lowStateE(1,k:k+bs-1)   = single(builtin('_paren',cellfun(@(c)c{7},hitran),1:bs)); 
    matObj.tempDependWidth(1,k:k+bs-1)  = single(builtin('_paren',cellfun(@(c)c{8},hitran),1:bs)); 
    matObj.pressureShift(1,k:k+bs-1)  = single(builtin('_paren',cellfun(@(c)c{9},hitran),1:bs)); 

    k = k + bs; 
    fprintf('.'); 
end 
fclose(fidr); 

nihai boyutu 21393408 bayt: Ön tahsisi ile

Başlangıç ​​kapalı şu şekildedir:

fid = fopen('01_hit12.par', 'r'); 
data = fread(fid, inf, 'uint8'); 
nlines = nnz(data == 10) + 1; 
fclose(fid); 

matObj.moleculeNumber = zeros(1,nlines,'uint8'); 
matObj.isotopeologueNumber = zeros(1,nlines,'uint8'); 
matObj.vacuumWavenumber = zeros(1,nlines,'double'); 
matObj.lineIntensity = zeros(1,nlines,'double'); 
matObj.airWidth = zeros(1,nlines,'single'); 
matObj.selfWidth = zeros(1,nlines,'single'); 
matObj.lowStateE = zeros(1,nlines,'single'); 
matObj.tempDependWidth = zeros(1,nlines,'single'); 
matObj.pressureShift = zeros(1,nlines,'single'); 

Sonra 10000 parçaları yazmayı, senin kod güncellenmiştir. Kullanım, hala oldukça verimsiz, ancak kontrolden çıkmayan, oldukça verimsiz olarak bozuluyor.

+0

Bir gecede bu gece çalışıyorum bir versiyonu var (bu kadar uzun sürmez, ama işten ayrılmadan önce koştum.) Sabah çalışabileceğim 20Mb dosyam olacak. ya da sabit diskimi yiyecek 30Gb bir canavarlık. Konuya dikkat ederek ve veri dosyasına sahipken, MATLAB'ın önde gelen mekânı dolaşmasıyla ilgili geçen hafta yayınladığım bağlantılı soruya bir göz atabilirseniz çok memnun olurum "textscan" kullanırken (bu yüzden "if (abs (hitranTemp) == 32); hitranTemp (1) = '0'; sonu 'bloğu). Verileri ayrıştırırken aynı şeyi görüyor musunuz? – craigim

+0

Şimdiye kadar yapılmalı. :) Makinemde sadece birkaç dakika sürdüm, çünkü 20'den fazla sadece 20 tane yazıyor. 0,000. – chappjc

+0

Bilgisayarım sadece 6 aylık, ama hala benim için oldukça yavaş çalışıyor. Çalıştırmaya başladım ve eşyalarımı topladığım zamana kadar hala çığlık atıyordum. – craigim