How to use cellfun in only cells with numbers or how to create a csv file with different elements (numbers and strings)?

7 visualizzazioni (ultimi 30 giorni)
I have a big cell array (22002x12) with multiple elements (strings and numbers) and I want to convert them to a CSV file but obviously I can't. So I was using cellfun to convert everything in either strings or numbers but is not possible.
So my question is if I have a cell array like this:
cellArray ={[ 1] '0.431089' '0.210426' '0.530389' '0.529967' '0.990659';
[ 2] '3.63584' '2.9894' '2.52868' '3.80065' '3.14567';
[ 3] [ 0] [ 0] '0.0593239' [ 0] '0.110771';
[ 9] '1.51064' '1.34827' '1.77354' '1.43471' '1.21254';
[ 10] '0.080619' [ 0] '0.0531488' '0.174925' '0.0496248';
[ 12] '0.129531' '0.169362' '0.170763' '0.21077' '0.0797323';
[ 13] '0.128055' '0.133946' '0.337633' '0.208367' '0.118236'}
how could I convert everything into numbers or cells using cellfun (or a better tool)?
I've been using :
matrix = cellfun(@str2num, cellArray)
Or how can I create a CSV file with this data?
I've been using :
csvwrite('new.csv',cellArray)
Thanks in advance!

Risposta accettata

Stephen23
Stephen23 il 4 Mag 2017
Modificato: Stephen23 il 4 Mag 2017
This is easy with num2str, which ignores strings. This has the advantage that the output CSV file contains exactly the data in those strings, because there is no loss/rounding/... from converting to numeric and back again.
% Mixed cell array:
C ={[ 1] '0.431089' '0.210426' '0.530389' '0.529967' '0.990659';
[ 2] '3.63584' '2.9894' '2.52868' '3.80065' '3.14567';
[ 3] [ 0] [ 0] '0.0593239' [ 0] '0.110771';
[ 9] '1.51064' '1.34827' '1.77354' '1.43471' '1.21254';
[ 10] '0.080619' [ 0] '0.0531488' '0.174925' '0.0496248';
[ 12] '0.129531' '0.169362' '0.170763' '0.21077' '0.0797323';
[ 13] '0.128055' '0.133946' '0.337633' '0.208367' '0.118236'};
% Cell array of character vectors:
D = cellfun(@num2str,C.','uni',0);
% Save data in CSV file:
fmt = repmat(',%s',1,size(C,2));
fmt = sprintf('%s\n',fmt(2:end));
fid = fopen('temp0.csv','wt');
fprintf(fid,fmt,D{:});
fclose(fid);
and this creates the following CSV file:
1,0.431089,0.210426,0.530389,0.529967,0.990659
2,3.63584,2.9894,2.52868,3.80065,3.14567
3,0,0,0.0593239,0,0.110771
9,1.51064,1.34827,1.77354,1.43471,1.21254
10,0.080619,0,0.0531488,0.174925,0.0496248
12,0.129531,0.169362,0.170763,0.21077,0.0797323
13,0.128055,0.133946,0.337633,0.208367,0.118236

Più risposte (2)

Andrei Bobrov
Andrei Bobrov il 4 Mag 2017
Modificato: Andrei Bobrov il 4 Mag 2017
l0 = cellfun(@ischar,cellArray);
cellArray(l0) = num2cell(str2double(cellArray(l0)));
or
l0 = cellfun(@isnumeric,cellArray);
cellArray(l0) = sprintfc('%d',[cellArray{l0}]);

Guillaume
Guillaume il 4 Mag 2017
You would be better off fixing whichever code you've used that creates a mixture of numbers and strings in the same column. You would also be better off using tables instead of cell array.
Failing that:
function x = maybeconvert(x)
%convert x to number if it is a string, or leave it as is if already number
if ischar(x)
x = str2double(x); %don't use str2num, it's a very dangerous function
end
You can use that with cellfun easily:
m = cellfun(@maybeconvert, cellArray);

Categorie

Scopri di più su Matrices and Arrays in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by