2012-05-14 119 views
3

我有一個csv文件,它包含2列4列數組,但行數不等。例如:Matlab從csv文件中讀取多個二維數組

2, 354, 23, 101 
3, 1023, 43, 454 
1, 5463, 45, 7657 

4, 543, 543, 654 
3, 56, 7654, 344 

... 

我需要能夠導入數據,這樣我可以每個數據塊上運行業務,但是csvreaddlmreadtextscan都不理的空行。

我似乎無法在任何地方找到解決方案,如何做到這一點?

PS:

這可能是值得指出的是,上述格式的文件實際上是包含只有一個數據塊(許多文件拼接我不希望有從數以千計的閱讀文件每次),因此塊之間的空白行可以更改爲任何其他分隔符/標記。這只是用python腳本完成的。

編輯:我的解決方案 - 基於/啓發的Petrichor下面

我更換了csvreadtextscan這是更快。然後我意識到,如果我用nan行代替空白行(修改我的python腳本),我可以刪除第二個慢點文本掃描。我的代碼是:

filename = 'data.csv'; 
fid = fopen(filename); 
allData = cell2mat(textscan(fid,'%f %f %f %f','delimiter',',')); 
fclose(fid); 

nanLines = find(isnan(allData(:,1)))'; 

iEnd = (nanLines - (1:length(nanLines))); 
iStart = [1 (nanLines(1:end-1) - (0:length(nanLines)-2))]; 
nRows = iEnd - iStart + 1; 

allData(nanLines,:)=[]; 

data = mat2cell(allData, nRows); 

其中0.28s(一個只有103000行文件)計算。我已經接受了petrichor的解決方案,因爲它最能解決我最初的問題。

+0

我想一個辦法是更換空行用類似的NaN,NaN的不同,NaN,NaN的,然後使用csvread加載數據後,或者類似的東西,你可以循環訪問數據,並且很容易地在matlab中提取塊。 – Dan

+0

我希望避免在導入之後通過數據循環(我假設),這隻會爲整個過程增加更多時間。另一方面,我發現迄今爲止,textscan是最快的導入方式? –

+0

如何不留下任何分隔線,而是創建第二個文件,該文件只是新塊開始時的行索引,然後使用此文件來定義要處理的行範圍,而不是爲每個塊創建單獨的矩陣? – Dan

回答

1
filename = 'data.txt'; 

%# Read all the data 
allData = csvread(filename); 

%# Compute the empty line indices 
fid = fopen(filename); 
lines = textscan(fid, '%s', 'Delimiter', '\n'); 
fclose(fid); 
blankLines = find(cellfun('isempty', lines{1}))'; 

%# Find the indices to separate data into cells from the whole matrix 
iEnd = [blankLines - (1:length(blankLines)) size(allData,1)]; 
iStart = [1 (blankLines - (0:length(blankLines)-1))]; 
nRows = iEnd - iStart + 1; 

%# Put the data into cells 
data = mat2cell(allData, nRows) 

,它爲您的數據如下:

data = 

    [3x4 double] 
    [2x4 double] 
+1

謝謝petrichor,一個很好的解決方案。正如我在上面的評論中提到的,我曾希望避免通過數據循環,但您的解決方案提供了一個良好的中間立場。根據我的實際數據計算:我發現csvread需要0.46秒,而使用textscan只需要0.26秒。因此,當我使用textscan替換csvread時,您的解決方案總共只需要0.49秒,這對我來說應該足夠快。我仍然對是否有'一步'的方式感到好奇......非常感謝 –