sscanf in a cell array

good morning, I have a cell array (of strings) and I want to replace strings with corresponding numbers, but using str2double that is incredibly slow. They suggested me to use
sscanf
instead, but I'm not able to use it in a cell array. Any suggestions? Thanks
let's take for instance, [{'0.001'},{'0.34'};{'89'},{'34'};{'0.898'},{'988'}]
and use sscanf

2 Comments

ludvikjahn
ludvikjahn on 26 Feb 2015
Edited: ludvikjahn on 26 Feb 2015
AH, I want the numbers to be in a matrix of the same dimensions ,no longer in a cell!
A neater way to define your cell array is like this:
{'0.001','0.34'; '89','34'; '0.898','988'}
and not by concatenating lots of individual cell arrays.

Sign in to comment.

Answers (2)

Testing on a 500 x 500 cell array of strings, this is the fastest method I could come up with:
m = reshape(str2num(strjoin(C)), size(C));
This takes about 2.1 seconds on my machine vs 5.4 seconds for the cyclist's answer and 4.7 seconds for Stephen's answer:
>>C = arrayfun(@(n) sprintf('%f', n), rand(500), 'UniformOutput', false);
>>tic; m1 = reshape(str2num(strjoin(C)), size(C)); toc
Elapsed time is 2.081194 seconds.
>>tic; m2 = cellfun(@str2double, C); toc
Elapsed time is 5.396223 seconds.
>>tic; m3 = cellfun(@(s)sscanf(s,'%f'), C); toc
Elapsed time is 4.759057 seconds.
However, you must have obtained that huge cell array by reading some file. Why not read that file as a matrix directly?

6 Comments

Although users with versions of MATLAB prior to 2012b(?) will find themselves without strjoin.
Using the same 500x500 cell array of strings, the explicit loop is the fastest that I could run:
>> tic; m2 = cellfun(@str2double, C); toc
Elapsed time is 16.494755 seconds.
>> tic; m3 = cellfun(@(s)sscanf(s,'%f'), C); toc
Elapsed time is 15.506557 seconds.
>> tic; m4 = temp(C); toc
Elapsed time is 8.343934 seconds.
where temp was defined simply as:
function X = temp(C)
X = nan(size(C));
for k = 1:numel(X)
X(k) = sscanf(C{k},'%f');
end
end
Guillaume:
I tried to get them as a Matrix, but they have commas as delimiter for decimal digits and using
importdata
I can only get them as string, otherwise I get a list of NaNs
and using your code
m = reshape(str2num(strjoin(C)), size(C));
it gives me the following error:
Error using strjoin (line 52)
First input must be a 1xN cell array of strings.
Actually C is not a 1xN cell array.
@ludvikjahn, in R2014b strjoin is happy with matrix, so you must have an earlier version of matlab where it can only deal with vectors. It's easily fixed though:
m = reshape(str2num(strjoin(C(:))), size(C));
On my machine it's still double the speed of Stephen's explicit loop.
As to the fact, that none of matlab built-in import function can't deal with comma as decimal point, I would submit a bug report, because it boggles the mind that that matlab can't deal with localisation properly.
Another approach, using a comma-separated list:
C = {'0.001','0.34'; '89','34'; '0.898','988'};
V = sscanf(sprintf(' %s',C{:}),'%f')
V = 6×1
0.0010 89.0000 0.8980 0.3400 34.0000 988.0000

Sign in to comment.

Are you doing it in parallel, or via loop?
Is this slow?
s = [{'0.001'},{'0.34'};{'89'},{'34'};{'0.898'},{'988'}]
n = cellfun(@str2double,s)

1 Comment

ludvikjahn
ludvikjahn on 26 Feb 2015
Edited: ludvikjahn on 26 Feb 2015
doing it in parallel, not in a loop... anyway,yes, imagine s as a 10000 x 10000 cell array

Sign in to comment.

Categories

Asked:

on 26 Feb 2015

Commented:

on 30 Jan 2023

Community Treasure Hunt

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

Start Hunting!