Efficiently convert cell to double

5 visualizaciones (últimos 30 días)
John
John el 22 de Mayo de 2012
Comentada: MacMilan ZHANG el 15 de Mzo. de 2022
Hi, I have a cell array of strings ("position") and need to convert the first cell column into a vector of doubles ("pointX"). The following loop works as intended, but takes a very long time. Is there a more efficient way to accomplish the same goal? Thank you.
parfor j = 1:length(position)
pointX(j,1) = str2num(cell2mat(position{j,1}(1)));
end
  6 comentarios
Oleg Komarov
Oleg Komarov el 23 de Mayo de 2012
You cannot do that.
You can try to change the problem at the core, e.g. by importing a file in a different way or by changing the routine that generates the cell, or you have to manipulate the cell array.
Jan
Jan el 24 de Mayo de 2012
@John, reading the textual description is still complictaed. It would reduce the chance of misunderstanding, if you post the Matlab code to create the test data and the wanted result, e.g.
position = {{'21', '34.5', '-17'}, {'324', '1e-19', '15'}}
result = [21, 324]
3 contributors tried to guess as good as they can, but there is a large chance, that we have wasted half an hour, because we did not understand the problem completely.

Iniciar sesión para comentar.

Respuestas (3)

Jan
Jan el 22 de Mayo de 2012
[EDITED: THIS DOES NOT MEET YOUR DEMANDS] Sorry, due to a missing example, I've overseen the fact, that you need the first column only. Before I guess to much around, could you please add some example values by editing the original question?
str2double is slow. sscanf is fast:
c = cell(1, 10000); % Create test data
for i = 1:numel(c)
c{i} = sprintf('%d', floor(rand*1000));
end
tic;
v1 = str2double(c);
toc
tic;
S = sprintf('%s*', c{:});
v2 = sscanf(S, '%d*');
toc
Elapsed time is 0.411949 seconds. (Matlab 2009a/64 Win7.)
Elapsed time is 0.013777 seconds.
But sprintf cannot pre-allocate sufficiently, such that a dedicated MEX-function for concatenating cell elements beat this, see FEX: CStr2String:
tic;
S = CStr2String(c, '*');
v2 = sscanf(S, '%d*');
toc
Elapsed time is 0.005835 seconds.
71 times faster. To my deep surprise calling SSCANF inside the MEX directly is not faster, although it avoids the expensive allocation of the large string, see e.g. FEX: String to double. Therefore I'd rely either on the pure Matlab sscanf(sprint()) or use CStr2String in addition.
  4 comentarios
madhan ravi
madhan ravi el 19 de Mzo. de 2019
@dzid: read about sscanf() in the documentation
MacMilan ZHANG
MacMilan ZHANG el 15 de Mzo. de 2022
Amazing speed up sscanf

Iniciar sesión para comentar.


Sean de Wolski
Sean de Wolski el 22 de Mayo de 2012
str2double() will be faster than str2num()
Also, could probably skip the parfor loop altogether and just call str2double() on the cell array of strings:
str2double({'3';'45'})

Oleg Komarov
Oleg Komarov el 23 de Mayo de 2012
To address the OP comments:
Suppose you have this fake input (6000 by 1 cell array where each cell is a 1 by 3 cellstring):
position = repmat({{'23','43','120'}},6000,1);
tic
% Manipulate into 6000 by 3
position = cat(1,position{:,1});
% Use str2double
position = str2double(position);
toc
Elapsed time is 0.754681 seconds.
If you want to achieve results faster, consider Jan's suggestions.
  6 comentarios
Jan
Jan el 24 de Mayo de 2012
I'd dare to call it "significant" also.
Daniel Shub
Daniel Shub el 24 de Mayo de 2012
With Oleg's pause on 64-bit Linux with R2011a I get:
0.6394 6.1356

Iniciar sesión para comentar.

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by