我需要在MATLAB中阅读以下csv
文件:
2009-04-29 01:01:42.000;16271.1;16271.1
2009-04-29 02:01:42.000;2.5;16273.6
2009-04-29 03:01:42.000;2.599609;16276.2
2009-04-29 04:01:42.000;2.5;16278.7
...
我想要三列:
timestamp; value1; value2
我尝试了这里描述的方法:
Reading date and time from CSV file in MATLAB
修改为:
filename = 'prova.csv';
fid = fopen(filename, 'rt');
a = textscan(fid, '%s %f %f', ...
'Delimiter',';', 'CollectOutput',1);
fclose(fid);
但是它会回转一个1x2的单元格,其第一个元素是a{1}='ÿþ2'
,另一个是空的。
我也试图适应我的情况这些问题的答案:
importing data with time in MATLAB
Read data files with specific format in matlab and convert date to matal serial time
但我没有成功。
如何导入csv
个文件?
编辑在@macduff回答后,我尝试在新文件中复制粘贴上面报告的数据并使用:
a = textscan(fid, '%s %f %f','Delimiter',';');
它有效。
不幸的是,这并没有解决问题,因为我必须处理自动生成的csv
文件,这似乎是造成奇怪的MATLAB行为的原因。
答案 0 :(得分:0)
尝试怎么样:
a = textscan(fid, '%s %f %f','Delimiter',';');
对我来说,我得到了:
a =
{4x1 cell} [4x1 double] [4x1 double]
因此a
的每个元素都对应于csv文件中的一列。这是你需要的吗?
谢谢!
答案 1 :(得分:0)
似乎你正确的方式。你提供的例子在这里没有问题,我得到你想要的输出。什么是1x2细胞?
如果我是你,我会再次尝试使用文件的较小子集,比如10行,并查看输出是否发生变化。如果是,则尝试100行等,直到找到4x1单元+ 4x2阵列分解为1x2单元的位置。可能是有一个空行或一个空字段或其他任何东西,这迫使textscan
收集额外级别的单元格中的数据。
请注意,'CollectOutput',1
会将最后两列收集到一个数组中,因此最终会得到1个包含4x1字符串的单元格数组,以及1个包含双精度数的4x2数组。这确实是你想要的吗?否则,请参阅@ macduff的帖子。
答案 2 :(得分:0)
我不得不解析像这样的大文件,我发现我不喜欢这个工作的文本扫描。我只是使用一个基本的while循环来解析文件,我使用datevec将时间戳组件提取到一个6元素的时间向量中。
%% Optional: initialize for speed if you have large files
n = 1000 %% <# of rows in file - if known>
timestamp = zeros(n,6);
value1 = zeros(n,1);
value2 = zeros(n,1);
fid = fopen(fname, 'rt');
if fid < 0
error('Error opening file %s\n', fname); % exit point
end
cntr = 0
while true
tline = fgetl(fid); %% get one line
if ~ischar(tline), break; end; % break out of loop at end of file
cntr = cntr + 1;
splitLine = strsplit(tline, ';'); %% split the line on ; delimiters
timestamp(cntr,:) = datevec(splitLine{1}, 'yyyy-mm-dd HH:MM:SS.FFF'); %% using datevec to parse time gives you a standard timestamp vector
value1(cntr) = splitLine{2};
value2(cntr) = splitLine{3};
end
%% Concatenate at the end if you like
result = [timestamp value1 value2];