2013-10-03 11 views
5

çıkarın. AşağıdakiBen büyük metin dosyası girişi (~ 500k hatları) ve</strong> ayrıştırma <strong>müteakip verilere ilişkin <strong>performans sorunu</strong> aşağıdakilere sahip performansındaki metin dosyası reoccuring satırları

Name Date Val1 val2 
--- ------- ---- ---- 
BA 2013-09-07 123.123 1232.22 
BA 2013-09-08 435.65756 2314.34 
BA 2013-09-09 234.2342 21342.342 

yazdım ve çalışma hangi kod edilir:

iki başlık satırları metin dosyası yerde yeniden ortaya çıkabilir bu anormallik ile aşağıdaki örnek yapıya sahip bir metin dosyası data.txt düşünün :

%# Read in file using textscan, read all values as string 

inFile = fopen('data.txt','r'); 
DATA = textscan(inFile, '%s %s %s %s'); 
fclose(inFile); 

%# Remove the header lines everywhere in DATA: 
%# Search indices of the first entry in first cell, i.e. 'Name', and remove 
%# all lines corresponding to those indices 

[iHeader,~] = find(strcmp(DATA{1},DATA{1}(1))); 
for i=1:length(DATA) 
    DATA{i}(iHeader)=[]; 
end 

%# Repeat again, the first entry corresponds now to '---' 

[iHeader,~] = find(strcmp(DATA{1},DATA{1}(1))); 
for i=1:length(DATA) 
    DATA{i}(iHeader)=[]; 
end 

%# Now convert the cells for column Val1 and Val2 in data.txt to doubles 
%# since they have been read in as strings: 

for i=3:4 
    [A] = cellfun(@str2double,DATA{i}); 
    DATA{i} = A; 
end 

Ben oder içinde bir dize DATA her yerde başlık satırları kaldırmak kaldırmak için muktedir olarak her şeyi okumayı seçti.

duruş zamanı kod yavaş parçası str2double rağmen [A] = cellfun(@str2double,DATA{i}) zaten str2num kıyasla daha hızlı bir seçimdir dönüşüm olduğunu söylüyor. İkinci en yavaş kısım textscan'dur.

soru bu sorunla başa çıkmak için daha hızlı bir yol var, şimdi?

ben daha ilişiğinizi gerektiğini varsa bana bildirin. Görmediğim çok belirgin bir çözüm varsa beni affet, şimdi üç haftalığına Matlab ile çalışıyorum. Bunu önlemek için veri toplama düzeltmek için mümkünse daha iyi olurdu uzun vadede rağmen

cevap

4

Eğer dosya (sizin durumunuzda tekrarlanan 2 headerlines) bir kısmını atlamak ve bir işlev çağrısında dosyanızı okuyacak CommentStyle denilen textscan bir seçeneği kullanabilirsiniz. doc says olarak

, CommentStyle 2 şekilde kullanılabilir: tek bir dize gibi '%' aynı hat veya iki dizeleri hücre dizisi üzerinde dize aşağıdaki karakterleri göz ardı etmek, örneğin {'/*', '*/'} gibi arasında karakter görmezden iki dizi (çizgi sonu dahil). Biz burada ikinci seçeneği kullanacağız: Name ve - arasındaki karakterleri kaldırın. Bitiş dizesi tekrarlanan bir - karakterden oluştuğundan, tüm dizgiyi belirtmemiz gerekir.

inFile = fopen('data.txt','r'); 
DATA = textscan(inFile, '%s %s %f %f', ... 
     'Commentstyle', {'Name';'--- ------- ---- ----'}); 
fclose(inFile); 

Sen datenum kullanarak anlamlı bir sayıya Tarih dizesini dönüştürebilirsiniz.

DATA_date = datenum(C{2}) 
+0

Bu benim veriler için iyi çalıştı. çift ​​dönüşüm dizesinin kullanımını önleme roughtly% 60 oranında zaman azalır! – Lukas

2

, sen TextScan içinde HeaderLines yararlanmak olabilir.

Bu örnek kod çalışır ancak preallocate C3/C4 mümkünse (yani, üst büyüklüğü bağlı tahmin etmek ve daha sonra kapalı sıfır kesme ile). Temel olarak, ilk textscan çağrı ile ilgili ilk iki satır atlama ve (örneğin, tekrar başlığı yoluyla yarıda) biçimi ile uyumlu bir hat edecek kadar devam ya da dosyanın sonuna ulaşıncaya kadar olacaktır. Gerçi, aldığı pozisyonu hatırlıyor.

Bir dahaki sefer textscan çağrıldığında, bu satırın geri kalanını ve bir sonraki tüm satırı atlar, ardından devam eder (eof ya da başka bir satır kümesi kümesi kadar). Dosyanın sonuna ulaşırsanız, metinler hatasız olarak çalışır, ancak length(data{3}) sıfır olmalıdır.

c3 = []; 
c4 = []; 
fid = fopen('data.txt'); 
data = textscan(fid,'%s %s %f %f','HeaderLines',2); 
l = length(data{3}); 
while l>0 %stop when we hit eof 
    c3 = [c3; data{3}]; 
    c4 = [c4; data{4}]; 
    data = textscan(fid,'%s %s %f %f','HeaderLines',2); 
    l = length(data{3}); 
end 
+0

Ben bu yaklaşımı çok seviyorum. Bu iki (veya gernerally K) başlık hatlarının belirli gerektirmeyen @Magla cevabın I karşılaştırması. Benim kodu için Magla tarafından çözüm yüzden en iyi uydurma cevap seçti uygulamak için daha kısaydı. Aynı zamanda, 'kullanarak hız açısından commentstyle'% 50 daha hızlıdır. – Lukas