[英]Reading data into MATLAB from a textfile
我有一個具有以下結構的文本文件:
1999-01-04
1,100.00
1,060.00
1,092.50
0
6,225
1,336,605
37
1999-01-05
1,122.50
1,087.50
1,122.50
0
3,250
712,175
14
...
該文件包含重復的八個值集合(一個日期后跟七個數字,每個數字各自獨立)。
我想把它讀入MATLAB並將值放到不同的向量中。 我試圖用幾種不同的方法來實現這一點,但沒有一種方法有效 - 都輸出了某種錯誤。
如果它很重要,我在Mac上這樣做。
編輯:這是我之前在答案中的代碼的較短版本...
如果您想直接讀取數據文件,而不必像dstibbe建議那樣先進行預處理,則以下內容應該有效:
fid = fopen('datafile.txt','rt');
data = textscan(fid,'%s %s %s %s %s %s %s %s','Delimiter','\n');
fclose(fid);
data = [datenum(data{1}) cellfun(@str2double,[data{2:end}])]';
上面的代碼將每組8個值放入8×N矩陣中,N是數據文件中8個線組的數量。 日期將轉換為序列日期編號,以便它可以包含在矩陣中的其他雙精度值中。 以下函數(在上面的代碼中使用)可能是有意義的: TEXTSCAN , DATENUM , CELLFUN , STR2DOUBLE 。
我提出另一個解決方案。 這是MATLAB代碼中最短的一個。 首先使用sed ,我們將文件格式化為CSV文件(逗號分隔,每行記錄在一行):
cat a.dat | sed -e 's/,//g ; s/[ \t]*$/,/g' -e '0~8 s/^\(.*\),$/\1\n/' |
sed -e :a -e '/,$/N; s/,\n/,/; ta' -e '/^$/d' > file.csv
說明 :首先我們刪除數千個逗號分隔符,並在每行末尾修剪空格添加逗號。 但是我們刪除每個第8行的結尾逗號。 最后,我們加入行並刪除空行。
輸出將如下所示:
1999-01-04,1100.00,1060.00,1092.50,0,6225,1336605,37
1999-01-05,1122.50,1087.50,1122.50,0,3250,712175,14
接下來在MATLAB中,我們只需使用textscan讀取每一行,第一個字段為字符串(轉換為num),其余為數字:
fid = fopen('file.csv', 'rt');
a = textscan(fid, '%s %f %f %f %f %f %f %f', 'Delimiter',',', 'CollectOutput',1);
fclose(fid);
M = [datenum(a{1}) a{2}]
並且得到的矩陣M是:
730124 1100 1060 1092.5 0 6225 1336605 37
730125 1122.5 1087.5 1122.5 0 3250 712175 14
使用腳本將文本文件修改為Matlab可以讀取的內容。
例如。 使它成為一個矩陣:
M = [
1999-01-04
1,100.00
1,060.00
1,092.50
0
6,225
1,336,605; <-- notice the ';'
37
1999-01-05
1,122.50
1,087.50
1,122.50
0
3,250; <-- notice the ';'
712,175
14
...
]
將其導入matlab並從矩陣中讀取各種向量。
注意:我的matlab有點生疏。 可能包含錯誤。
一旦你閱讀了數據,你想要的數據形式並不完全清楚。 下面的代碼將它全部放在一個矩陣中,每行代表文本文件中的一組8行。 您可能希望對不同的列使用不同的變量,或者(如果您有權訪問統計工具箱),請使用數據集數組。
% Read file as text
text = fileread('c:/data.txt');
% Split by line
x = regexp(text, '\n', 'split');
% Remove commas from numbers
x = regexprep(x, ',', '')
% Number of items per object
n = 8;
% Get dates
index = 1:length(x);
dates = datenum(x(rem(index, n) == 1));
% Get other numbers
nums = str2double(x(rem(index, n) ~= 1));
nums = reshape(nums, (n-1), length(nums)/(n-1))';
% Combine dates and numbers
thedata = [dates nums];
您還可以查看函數textscan
以了解解決問題的其他方法。
與Richie相似。 使用str2double將文件字符串轉換為雙精度數。 此實現逐行處理,而不是使用正則表達式打破文件。 輸出是各個向量的單元陣列。
function vectors = readdata(filename)
fid=fopen(filename);
tline = fgetl(fid);
counter = 0;
vectors = cell(7,1);
while ischar(tline)
disp(tline)
if counter > 0
vectors{counter} = [vectors{counter} str2double(tline)];
end
counter = counter + 1
if counter > 7
counter = 0;
end
tline = fgetl(fid);
end
fclose(fid);
這有正則表達式檢查,以確保您的數據格式良好。
fid = fopen('data.txt','rt'); %these will be your 8 value arrays val1 = []; val2 = []; val3 = []; val4 = []; val5 = []; val6 = []; val7 = []; val8 = []; linenum = 0; % line number in file valnum = 0; % number of value (1-8) while 1 line = fgetl(fid); linenum = linenum+1; if valnum == 8 valnum = 1; else valnum = valnum+1; end %-- if reached end of file, end if isempty(line) | line == -1 fclose(fid); break; end switch valnum case 1 pat = '(?\d{4})-(?\d{2})-(?\d{2})'; % val1 (e.g. 1999-01-04) case 2 pat = '(?\d*[,]*\d*[,]*\d*[.]\d{2})'; % val2 (e.g. 1,100.00) [valid up to 1billion-1] case 3 pat = '(?\d*[,]*\d*[,]*\d*[.]\d{2})'; % val3 (e.g. 1,060.00) [valid up to 1billion-1] case 4 pat = '(?\d*[,]*\d*[,]*\d*[.]\d{2})'; % val4 (e.g. 1,092.50) [valid up to 1billion-1] case 5 pat = '(?\d+)'; % val5 (e.g. 0) case 6 pat = '(?\d*[,]*\d*[,]*\d+)'; % val6 (e.g. 6,225) [valid up to 1billion-1] case 7 pat = '(?\d*[,]*\d*[,]*\d+)'; % val7 (e.g. 1,336,605) [valid up to 1billion-1] case 8 pat = '(?\d+)'; % val8 (e.g. 37) otherwise error('bad linenum') end l = regexp(line,pat,'names'); % l is for line if length(l) == 1 % match if valnum == 1 serialtime = datenum(str2num(l.yr),str2num(l.mo),str2num(l.dy)); % convert to matlab serial date val1 = [val1;serialtime]; else this_val = strrep(l.val,',',''); % strip out comma and convert to number eval(['val',num2str(valnum),' = [val',num2str(valnum),';',this_val,'];']) % save this value into appropriate array end else warning(['line number ',num2str(linenum),' skipped! [didnt pass regexp]: ',line]); end end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.