2014-05-08 14 views
3

我有一個數據文件,每行數據量不等,我想以數組形式加載到Matlab中。舉個例子,假設數據文件看起來像Matlab - 用不同的線長讀取文件

1 2 
3 4 5 6 
7 
8 9 10 

我想把它讀入Matlab的一個數組,看起來像

1 2 nan nan 
3 4 5 6 
7 nan nan nan 
8 9 10 nan 

我可以過的所有行做一個循環做到這一點該文件但我的文件非常大,我正在尋找一個有效的解決方案。任何想法將不勝感激。如果有幫助,我也知道整個文件的最大行長度的上限。

+1

可以我們'textread' – bla

+1

是的,你應該看看這裏所示的例子靠近你需要的東西:http://stackoverflow.com/questions/14158165/read-block-of-data-into-matlab-array – beedot

回答

2

雖然Divakar的答覆工作,如果你沒有在文本文件中的零的任何值,這可能不是一般這樣的情況。例如,如果你的文本數組是

1 2 3 
4 0 
5 6 0 7 8 

然後Divakar的結果將是:

1 2 3 nan nan 
4 nan nan nan nan 
5 6 nan 7 8 

而你真的想:

1 2 3 nan nan 
4 0 nan nan nan 
5 6 0 7 8 

實現最簡單的方法是打開dlmread函數(只需在文本編輯器中輸入dlmread並按Ctrl + D將其打開)。請確保將此文件另存爲您使用其他名稱的目錄(即dlmread_nan.m)中的單獨文件。

再往代碼(在我的版本線126)的這一部分:

if isempty(delimiter) 
    result = textscan(fid,'',nrows,'headerlines',r,'headercolumns',c,... 
         'returnonerror',0,'emptyvalue',0, 'CollectOutput', true); 
else 
    delimiter = sprintf(delimiter); 
    whitespace = setdiff(sprintf(' \b\t'),delimiter); 
    result = textscan(fid,'',nrows,... 
        'delimiter',delimiter,'whitespace',whitespace, ... 
        'headerlines',r,'headercolumns',c,... 
        'returnonerror',0,'emptyvalue',0,'CollectOutput', true); 
end 

,並在這兩種情況下更改「emptyvalue」後的價值爲NaN,而不是0保存文件。它應該是這樣的:

if isempty(delimiter) 
    result = textscan(fid,'',nrows,'headerlines',r,'headercolumns',c,... 
         'returnonerror',0,'emptyvalue',NaN, 'CollectOutput', true); 
else 
    delimiter = sprintf(delimiter); 
    whitespace = setdiff(sprintf(' \b\t'),delimiter); 
    result = textscan(fid,'',nrows,... 
        'delimiter',delimiter,'whitespace',whitespace, ... 
        'headerlines',r,'headercolumns',c,... 
        'returnonerror',0,'emptyvalue',NaN,'CollectOutput', true); 
end 

爲了讓您的陣列,使用此:

result = dlmread_nan('text.txt', ' '); 
%%//This will give you exactly what you're looking for. 

這是一個有點繁瑣,但是從MATLAB的圖書館拷貝,這可能會是很多更強大,沒有錯誤比自己從頭開始編寫它。

+0

+1。好建議。 – rayryeng

+0

您可能想要在您引用我的解決方案的位置編輯您的答案,因爲我在數據爲零時添加了案例解決方案:) – Divakar

2

案例1:沒有零數據

這種技術使用dlmread是一個空的地方固有轉換成零,然後我們需要爲需要,以獲得所需的輸出者轉變爲NaN的。

代碼

out = dlmread(textfile_path, ' ') %%// textfile_path is path to your text file 
out(out==0)=NaN %%// out is your desired output 

輸入

1 2 
3 4 5 6 
7 
8 9 10 

輸出

out = 
    1  2 NaN NaN 
    3  4  5  6 
    7 NaN NaN NaN 
    8  9 10 NaN 

案例2:用零數據,因此warrantes額外的照顧來保護這些零

這種方法使用textscan,因爲他們是保持零細胞柱陣列圍繞着數據導入,使空的地方爲NaN的。唯一的問題是,對於最後一行,由於沒有任何空位(如果最後一行不是最長行),長度不等於行數。同樣,我們需要幾行額外的代碼。

方法1:

代碼

fid = fopen(textfile_path,'r'); %%// textfile_path is path to your text file 
data1 = textscan(fid,''); 
fclose(fid); 

lens = cellfun(@numel,data1) 
out = NaN(max(lens),numel(lens)) %%// out will be your output 
for k = 1:numel(lens) 
    out(1:lens(k),k) = data1{:,k} 
end 

方法2(較短版本):

代碼

fid = fopen(textfile_path,'r'); %%// textfile_path is path to your text file 
data1 = textscan(fid,''); 
fclose(fid); 

n1 = find(diff(cellfun(@numel,data1))~=0) 

%%// out will be your output 
out = [horzcat(data1{:,[1 n1]}) [horzcat(data1{:,[n1+1:end]}) ; NaN(1,numel(data1)-n1)]] 

輸入

1 2 3 
4 0 
5 6 0 7 8 
0 0 

輸出

out = 
    1  2  3 NaN NaN 
    4  0 NaN NaN NaN 
    5  6  0  7  8 
    0  0 NaN NaN NaN 
+1

謝謝Divakar。textread已滿足我的目的,但我會將其標記爲將來參考。 – Dinesh

0

在這種情況下?

輸入

1 2 3 6 
4 5 
1 0 7 8 
0 0  5 

怎麼辦?

Textscan將是危險的,因爲它不會保留數位