使用混合类型数据读取CSV

时间:2012-09-13 16:28:39

标签: matlab csv import

我需要在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行为的原因。

3 个答案:

答案 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];