How to convert string to number and process underscores? (e.g. '57_77_' to 57.77)

How do you convert a string with underscores to a number, namely '57_77_' to 57.77? What commands would you use?
I am looking through the documentation, e.g. join, compose, sprintf, extractBefore, trying to figure out how to process such a string, namely to execute the steps:
  1. delete final '_'
  2. convert '_' to decimal point '.'
  3. convert string to number

 Risposta accettata

Faster and more efficient than using str2num (which hides a slow eval call inside) is to simply use the low-level function sscanf:
>> sscanf(strrep('57_77_','_','.'),'%f')
ans = 57.770
This is ten times faster than the accepted answer (1e4 iterations):
Elapsed time is 0.277028 seconds. % my code
Elapsed time is 2.63426 seconds. % accepted answer

5 Commenti

+1. str2double might also be a better alternative for str2num
"str2double might also be a better alternative for str2num"
The documentation states: " str2double: Similar to str2num, but offers better performance..."
But str2double is still not as fast a using low-level sscanf.
Replacing str2num with sscanf dropped the execution time from 19 s to 17 s for 40 iterations (apparently my bottleneck is something else -- perhaps reading the CSV files with detectImportOptions). Any thoughts how to further expedite this code? (Edit: I am now reading your other answer which appears also to answer this one.)
function output = GetVolumesFromDVH(organ)
NoPt = 40;
output = zeros(NoPt,1);
searchstring = [organ,'_'];
for fileloop = 1:NoPt
filepath = fullfile('DVH','blurred',sprintf('%u.csv',fileloop));
output(fileloop) = GetOrgVol(filepath,searchstring);
end
end
function volume = GetOrgVol(filepath,searchstring)
% get list of variable names
opts = detectImportOptions(filepath, 'NumHeaderLines', 1);
% we find the column containing the organ volume
OrganSearching = regexp(opts.VariableNames,searchstring);
for loop = 1:numel(opts.VariableNames)
if OrganSearching{loop} == 1
index = loop;
end
end
% extract volume from said string
volume = extractAfter(opts.VariableNames{index},'Volume_');
volume = sscanf(strrep(volume,'_','.'),'%f');
end
If the CSV files all have the exactly same format then there is no reason why detectImportOptions has to be called 40 times. Why not move it out of the function, call it once before the loop, and pass that data as an input argument?
The goal is to read the table variable names in each file: Their order, number, and name differ. So I was thinking I needed to call it each time since the variable names generally differ each time.
Isn't there a better command than detectImportOptions since .VariableNames is all I need?

Accedi per commentare.

Più risposte (3)

The wise thing would be to first convert underlines to dots by using regexprep or strrep:
a=regexprep(a,'_','.')
or
a=strrep(a,'_','.')
and then delete the last character by
a(end)=[]
a=str2num(a)
Other way would be doing this by using regexp:
idx=regexp(a,'_')
a(idx)=['.',' ']
a=str2num(a)

2 Commenti

you can remove the last element of the string before the replacement of the underscore ...

Accedi per commentare.

all in one go:
a = '12_23_'
v = str2num(strrep(a(1:end-1), '_', '.'))

2 Commenti

You say all in one go but you use two functions in one line, actually it is all in two go :)
haha, actually it is even three if you take indexing into account.

Accedi per commentare.

Here is one method that works, but I am not happy using a cell wrapper just to use Walter Roberson's cellfun; I'm sure there's a better way ...
volume = '57_77_';
volume = cellfun(@(S) S(1:end-1), {volume}, 'Uniform', 0);
volume = volume{1};
volume = regexprep(volume,'_','.');
volume = str2num(volume)
Result:
volume =
57.7700

4 Commenti

Check mine and Jos' answer.
Yes, I reloaded the page to find this burst of activity!
I'm glad to see I can simply use volume(end) = [] to replace
volume = cellfun(@(S) S(1:end-1), {volume}, 'Uniform', 0);
volume = volume{1};
Why did you recommend replacing it with a question mark?
That was a misunderstanding, I have just edited it. Sorry for the misunderstanding.
Oh! Sorry for my awkward question -- I accidentally combined Japanese and English grammar. (or else made a Japanese-type English grammar mistake) I will edit my question to clarify, too, if not simply for the sake of English.

Accedi per commentare.

Categorie

Community Treasure Hunt

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

Start Hunting!

Translated by