2010-01-11 69 views
6

我已經編寫了一個腳本,將其輸出保存爲CSV文件供以後參考,但用於導入數據的第二個腳本只需要很長時間就可以讀取。在MATLAB中導入CSV文件的最快方法

的數據是以下格式:

Item1,val1,val2,val3 
Item2,val4,val5,val6,val7 
Item3,val8,val9 

其中標頭是在最左邊的列中,並且所述數據值佔用的行的其餘部分。一個主要困難是對於每個測試項目,數據值的數組可以是不同的長度。我將它保存爲一個結構體,但我需要能夠在MATLAB環境之外進行編輯,因爲有時我必須刪除沒有安裝MATLAB的計算機上的壞數據行。所以真的,我的問題的第一部分是:我應該以另一種格式保存數據嗎?問題的

第二部分: 我試過importdatacsvreaddlmread,但我不知道這是最好的,或者如果有一個更好的解決方案。現在我正在使用我自己的腳本,使用循環和fgetl,這對於大文件來說非常慢。有什麼建議麼?

function [data,headers]=csvreader(filename); %V1_1 
fid=fopen(filename,'r'); 
data={}; 
headers={}; 
count=1; 
while 1 
     textline=fgetl(fid); 
     if ~ischar(textline), break, end 
     nextchar=textline(1); 
     idx=1; 
     while nextchar~=',' 
     headers{count}(idx)=textline(1); 
     idx=idx+1; 
     textline(1)=[]; 
     nextchar=textline(1); 
     end 
     textline(1)=[]; 
     data{count}=str2num(textline); 
     count=count+1; 
end 
fclose(fid); 

(我知道這可能是非常編寫的代碼 - 我是工程師,不是程序員,請不要對我大喊大叫 - 改進建議將受到歡迎,雖然)

回答

10

或許,這將使得數據更容易,如果你可以墊NaN值的文件時,你的第一個腳本創建它來閱讀:

Item1,1,2,3,NaN 
Item2,4,5,6,7 
Item3,8,9,NaN,NaN 

,或者你甚至可以只打印空字段:

Item1,1,2,3, 
Item2,4,5,6,7 
Item3,8,9,, 

當然,爲了正確填充,您需要知道所有項目的最大值是多少。通過以上兩種格式,你可以再使用的標準文件閱讀功能之一,像TEXTSCAN例如:

>> fid = fopen('uneven_data.txt','rt'); 
>> C = textscan(fid,'%s %f %f %f %f','Delimiter',',','CollectOutput',1); 
>> fclose(fid); 
>> C{1} 

ans = 

    'Item1' 
    'Item2' 
    'Item3' 

>> C{2} 

ans = 

    1  2  3 NaN %# TEXTSCAN sets empty fields to NaN anyway 
    4  5  6  7 
    8  9 NaN NaN 
3

相反解析字符串一個TextLine一個字符的時間。你可以使用的strtok打破串起來,例如

stringParts = {}; 
tline = fgetl(fid); 
if ~ischar(tline), break, end 
i=1; 
while 1 
    [stringParts{i},r]=strtok(tline,','); 
    tline=r; 
    i=i+1; 
    if isempty(r), break; end 
end 

% store the header 
headers{count} = stringParts{1}; 

% convert the data into numbers 
for j=2:length(stringParts) 
    data{count}(j-1) = str2double(stringParts{j}); 
end 
count=count+1; 
+0

+1推薦strtok - 我不知道它存在之前 – Doresoom 2010-01-11 19:44:51

0

Q1)如果你知道列的最大數量,你可以填寫與南 也是空的條目,如果所有值均爲數字,你真的需要「Item#」列?如果是,則只能使用「#」,因此所有數據都是數字。 Q2)讀取num的最快方法。來自沒有mex-files的文件的數據是csvread。 我儘量避免使用CSV文件中的字符串,但如果我有,我用我的csv2cell功能:

http://www.mathworks.com/matlabcentral/fileexchange/20135-csv2cell

+0

項目#列實際上是文本標籤,所以是的,我確實需要它。我應該澄清一點。 – Doresoom 2010-01-11 19:33:15

1

我已經受夠了在Matlab讀取CSV數據同樣的問題,我很驚訝由此得到的支持很少,但後來我找到了導入數據工具。我在r2015b。

在「主頁」選項卡的頂部欄上,單擊「導入數據」並選擇您想要閱讀的文件。一個應用程序窗口會想出這樣的:

Import Data tool screenshot

在「導入選擇」你要「生成函數」的選項,它給你相當多的自定義選項,包括如何填補空白單元格,以及您希望輸出數據結構是什麼。另外它由MathWorks編寫,所以它可能利用最快的可用方法來讀取csv文件。這幾乎是我的檔案中的瞬間。