Textscan reading in floats and str2num dropping ending zeros

MATLAB VERSION: R2007a - I know...my company is up on the times.
I'm trying to read in data from a tab delimited text file that looks like:
ABCDEF 2012.190.18465.356 0 TRUE
MKJIJN 2012.190.19305.376 b7 183
My current scan string is:
SCAN_STR = '%s\t%f.%f\t%s\t%s\t%*s';
TEMP = textscan(FID, SCAN_STR, 'delimiter', '\t');
Matlab reads in the data as (sample of first to save time):
TEMP{1} = 'ABCDEF'
TEMP{2} = 2012.19
TEMP{3} = 18465.365
TEMP{4} = '0'
TEMP{5} = 'TRUE'
Why does it drop the ending zero for TEMP{2}? 19 vs. 190 is a big difference. Is there any way for me to make sure the ending zero remains?
When I try to read it in as a string:
SCAN_STR = '%s\t%s\%s\t%s\t%*s';
All are strings. Now:
TEMP{2} = '2012.190.18465.356'
I split it using:
YRDY = cellfun(@(x)x(1:8),TEMP{2},'Un',0);
YRDY = '2012.190'
Using str2num:
YRDYnum = cellfun(@(x)str2num(x), YRDY, 'Un',0);
YRDYnum = 2012.19
Why does this happen? There has to be some way for me to keep the ending zero.
Thanks, Mike

 채택된 답변

Kelly Kearney
Kelly Kearney 2013년 7월 16일
If you read the year-day combo string in as a number, or convert from string to number, it's going to treat the value like a number. And in that case, 2012.19 is the same as 2012.190. You probably want to split the year and day values apart before converting to a number:
% Recreate your test
str = sprintf('%s\t%s\t%s\t%s\n', 'ABCDE','2012.190.18465.356', '0', 'TRUE', 'MKJIJN', '2012.190.19305.376', 'b7', '183')
str =
ABCDE 2012.190.18465.356 0 TRUE
MKJIJN 2012.190.19305.376 b7 183
% Read everything as strings
data = textscan(str, '%s%s%s%s', 'delimiter', '\t');
% Parse dates
yrday = data{2};
yrday = cellfun(@(x) regexp(x, '\.', 'split'), yrday, 'uni', 0);
yrday = cat(1, yrday{:});
yrday = cellfun(@str2num, yrday);

댓글 수: 2

Ok. Thats what I was going forward with. Then that presents a problem with my TEMP{3}. For me TEMP{3} is time. Now if that ends in a zero it could mess up my results. Is the only way around this to separate my time into sec.ms? I guess I'm confused on how MATLAB sees 2012.19 the same as 2012.190. Why does MATLAB drop the ending zero? MATLAB doesn't see zero as a place holder/number so it assumes its not needed?
It's a little roundabout, but you can put the seconds and milliseconds back together prior to converting to a number
yrday = data{2};
yrday = cellfun(@(x) regexp(x, '\.', 'split'), yrday, 'uni', 0);
yr = cellfun(@str2num, yrday(:,1));
day = cellfun(@str2num, yrday(:,2));
sec = cellfun(@(x,y) str2num([x '.' y]), yrday(:,3), yrday(:,4));
There's probably a way to split only along the first two instances of \. in the regular expression, but I don't know it off the top of my head.
As for why it behaves this way, I think the confusion is arising over the use of the period as a delimiter vs its use as a decimal point. When converting from string to number, Matlab assumes . is the decimal, so there's no need to hold on to trailing zeros after a decimal point (Matlab doesn't assume significant digits or anything like that). In your case, it seems as though the . is being used for both purposes: to delimit years, days, and seconds; and as a decimal point in the seconds. So you need to break apart the strings first, then convert to numeric form once you have removed all non-decimal .'s.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

질문:

2013년 7월 16일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by