Matlab: Convert a binary vector array to an array of strings

map1 = containers.Map({'212','2','12','44'},[4,5,6,7]); keyset = str2double(keys(map1)); 

Now I am doing a set of keyboard operations that will return

 Keyset= [203,2,12,39]; 

I am tired of the following:

 num2cell(num2str(keyset)); num2cell(num2str(keyset,1)); num2cell(num2str(keyset,'%11.0g')); num2cell(num2str(keyset,3)); 

all of the above gave strange results in the last array of cells. I just need integers to be used as keys for another container card.

+8
string arrays double matlab cell
source share
4 answers

I offer 5 additional solutions, three of which are 4-5 times faster than the proposed solutions. The following lessons can be learned from this:

  • num2str slow
  • cellfun and arrayfun can add significant overhead
  • There are many ways to convert a numeric array into an array of row cells.

Three high-performance solutions are very similar in performance:

Looping to Assign Cell Elements

 n4 = length(Keyset); tmp4 = cell(n4,1); for i4 = 1:n4 tmp4{i4} = sprintf('%i',Keyset(i4)); end 

Convert everyone to string and call textscan

 tmp6 = textscan(sprintf('%i\n',Keyset'),'%s'); tmp6 = tmp6{1}; 

Convert everyone to string and call regexp .

 tmp3 = regexp(sprintf('%i ',Keyset),'(\d+)','match'); 

Here is the full test code with timings:

 function t = speedTest t=zeros(7,1); for ii=1:100, Keyset=randi(1,10,100); % random keys tic; eval( [ 'tmp1 = { ', sprintf(' %d ', Keyset), ' }; '] ); t(1)=t(1)+toc; tic; tmp2=arrayfun(@num2str, Keyset, 'Uniform', false); t(2)=t(2)+toc; tic; tmp3 = regexp(sprintf('%i ',Keyset),'(\d+)','match'); t(3) = t(3)+toc; tic; n4 = length(Keyset); tmp4 = cell(n4,1); for i4 = 1:n4 tmp4{i4} = sprintf('%i',Keyset(i4)); end t(4) = t(4)+toc; tic; n5 = length(Keyset); tmp5 = cell(n5,1); for i5 = 1:n5 tmp4{i5} = num2str(Keyset(i5)); end t(5) = t(5)+toc; tic; tmp6 = textscan(sprintf('%i\n',Keyset'),'%s'); tmp6 = tmp6{1}; t(6) = t(6)+toc; tic; tmp7 = num2cell(Keyset); tmp7 = cellfun(@(x)sprintf('%i',x),tmp7,'uni',false); t(7) = t(7)+toc; end; t t = 1.7820 21.7201 0.4068 0.3188 2.2695 0.3488 5.9186 
+13
source share

What about:

 arrayfun(@num2str, Keyset, 'Uniform', false)' 

which should give an array of 4 by 1 cells for your example:

 ans = '203' '2' '12' '39' 
+7
source share

What about:

 eval( [ 'NewKeySetStr = { ', sprintf(' %d ', Keyset), ' }; '] ); NewKeySetStr 

I'm not sure if this is the most elegant way to achieve the desired results, but it seems to work ...

Comparison of runtime with Eitan solution:

 t=zeros(2,1); for ii=1:100, Keyset=randi(1,10,100); % random keys tic; eval( [ 'NewKeySetStr = { ', sprintf(' %d ', Keyset), ' }; '] ); t(1)=t(1)+toc; tic; tmp=arrayfun(@num2str, Keyset, 'Uniform', false); t(2)=t(2)+toc; end; t 

Productivity:

 t = 0.3986 2.2527 

The proposed solution seems to be faster.

Note: it seems that the current implementation of cellfun not optimized for speed. Rumor has it that in future versions of Mathworks intends to introduce a more efficient implementation of cellfun . Thus, the Eitan solution may not be optimal in the current version, but it seems to be a good practice for Matlab skills.

+3
source share

Learned how to improve regex for large integers using split functionality. Also, I was somewhat misled by one of the Jonas solutions, which did not evaluate all sprintf calls in a for loop. Edit: The new 2016 line functionality suggested in the comments has also been added.

 t = speedTest() function t = speedTest t=zeros(5,1); for ii=1:100 Keyset=randi(10000000,10,1000); % random keys tic; n4 = numel(Keyset); % changed to numel (length only gives number of columns) tmp1 = cell(n4,1); for i4 = 1:n4 tmp1{i4} = sprintf('%i',Keyset(i4)); end t(1) = t(1)+toc; tic; tmp2 = regexp(sprintf('%i ',Keyset),'(\d+)','match'); t(2) = t(2)+toc; tic; tmp3 = regexp(sprintf('%i ',Keyset),' ','split'); tmp3(end) = []; t(3) = t(3)+toc; tic; tmp4 = string(Keyset(:)); t(4) = t(4)+toc; # test in case you want to go back to characters tic; tmp5 = char(string(Keyset(:))); t(5) = t(5)+toc; end end 

The regexp breakup solution provides slightly better performance, and the string method is even faster:

 t = 6.1916 1.1292 0.8962 0.6671 0.7523 
0
source share

All Articles