Put the leading number (not sequence ) corresponding to the number in the column

1 visualizzazione (ultimi 30 giorni)
Dear matlab community
I've a problem with putting lead of number correspended with column. Say I've lead number like: 1, 2, 5, 55, 555, 56, 57, 58, 59, 8. In other word, i want all numbers that lead by 1 places in column 1, lead 2 in column 2, lead 5 in column 3, lead 55 in column 4, .... lead 8 ini column 10..
for easy ilustration you can see below figure:
the data:
rowcell={'10302','20245','50108','55112','58013','85911',[],[];
'10268',[],'55095','56099','58014','59944','81502',[];
'10308','20258','50054','55558','56019','83511',[],[];
'10307','20258','50073','55077','56018','56021','58162','83511';
'10325','20232','50082','55086',[],[],[],[];
'10276','20228',[],'56085','59013','81531',[],[]};
im stuck here (edited):
criteria = [{'1xxxx'},{'2xxxx'},{'5xxxx'},{'55xxx'},{'555xx'},{'56xxx'},{'57xxx'},{'58xxx'},{'59xxx'},{'8xxxx'}];
[m3,~]=size(rowcell);
n3=repmat(length(criteria),m3,1);
rowcellnew = cell(m3,max(n3));
...
tks for your help
  2 Commenti
Ahmed Mansour
Ahmed Mansour il 7 Giu 2022
Hi , I tried to do it in a very basic way as I'm a beginner in MATLAB. Also you don't have any '57xxx' elements in the rowcell cell array.
rowcelltemp=rowcell;
criteria=cell(10,1);
criteria_index=zeros(10,1);
for i =1:48
A= rowcelltemp{i};
if(~(size(A,1)==0)&&all((A(1)=='1')))
criteria_index(1)=criteria_index(1)+1;
criteria{1,criteria_index(1)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1)=='2')))
criteria_index(2)=criteria_index(2)+1;
criteria{2,criteria_index(2)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1:3)=='555')))
criteria_index(5)=criteria_index(5)+1;
criteria{5,criteria_index(5)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1:2)=='55')))
criteria_index(4)=criteria_index(4)+1;
criteria{4,criteria_index(4)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1:2)=='56')))
criteria_index(6)=criteria_index(6)+1;
criteria{6,criteria_index(6)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1:2)=='57')))
criteria_index(7)=criteria_index(7)+1;
criteria{7,criteria_index(7)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1:2)=='58')))
criteria_index(8)=criteria_index(8)+1;
criteria{8,criteria_index(8)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1:2)=='59')))
criteria_index(9)=criteria_index(9)+1;
criteria{9,criteria_index(9)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1:2)=='8')))
criteria_index(10)=criteria_index(10)+1;
criteria{10,criteria_index(10)}=A;
continue;
end
if(~(size(A,1)==0)&&all((A(1)=='5')))
criteria_index(3)=criteria_index(3)+1;
criteria{3,criteria_index(3)}=A;
continue;
end
end
criteria=criteria';
eko supriyadi
eko supriyadi il 7 Giu 2022
overall your step is ok, but if we look at detail (in row perspective) this is still not arrange.. Your empty matrix just remove in the last row..

Accedi per commentare.

Risposta accettata

eko supriyadi
eko supriyadi il 13 Giu 2022
this is my effort to solve this problem
load rowcell.mat
%empty data is indicated by []
empty_idx_3d = cellfun(@isempty,seksi3d);
%Then we fill the empty cell with '00000', because all numbers are 5 digits
seksi3d(empty_idx_3d) = {'00000'};
%firstly, determine the first one-digit number
[a,b]=size(seksi3d);
lead1digit={};
for i=1:a
for j=1:b
lead1digit{i,j}=seksi3d{i,j}(1);
end;end
%and determine the first two digit number
lead2digit={};
for i=1:a
for j=1:b
lead2digit{i,j}=seksi3d{i,j}(1:2);
end;end
%and determine the first three digit number
lead3digit={};
for i=1:a
for j=1:b
lead3digit{i,j}=seksi3d{i,j}(1:3);
end;end
%we determine the location of 12 types of number heads with the following formula
%but be careful with double digit heads like 5,55,555,8, and 80
find1xxxx=find(strcmp({lead1digit{:}},'1'));
find2xxxx=find(strcmp({lead1digit{:}},'2'));
find5xxxx=find(strcmp({lead1digit{:}},'5'));
find6xxxx=find(strcmp({lead1digit{:}},'6'));
find8xxxx=find(strcmp({lead1digit{:}},'8'));
find80xxx=find(strcmp({lead2digit{:}},'80'));
find55xxx=find(strcmp({lead2digit{:}},'55'));
find56xxx=find(strcmp({lead2digit{:}},'56'));
find57xxx=find(strcmp({lead2digit{:}},'57'));
find58xxx=find(strcmp({lead2digit{:}},'58'));
find59xxx=find(strcmp({lead2digit{:}},'59'));
find555xx=find(strcmp({lead3digit{:}},'555'));
find5xxxx(ismember(find5xxxx,[find55xxx,find56xxx,find57xxx,find58xxx,find59xxx,find555xx]))=[];
find55xxx(ismember(find55xxx,find555xx))=[];
find8xxxx(ismember(find8xxxx,[find80xxx]));
%findall=[find1xxxx find2xxxx find5xxxx find55xxx find555xx find56xxx find57xxx find58xxx find59xxx find6xxxx find8xxxx find80xxx];
%applied modulus function
for i=1:a
find1xxxxa=mod(find1xxxx,a);
find2xxxxa=mod(find2xxxx,a);
find5xxxxa=mod(find5xxxx,a);
find6xxxxa=mod(find6xxxx,a);
find8xxxxa=mod(find8xxxx,a);
find80xxxa=mod(find80xxx,a);
find55xxxa=mod(find55xxx,a);
find56xxxa=mod(find56xxx,a);
find57xxxa=mod(find57xxx,a);
find58xxxa=mod(find58xxx,a);
find59xxxa=mod(find59xxx,a);
find555xxa=mod(find555xx,a);
end
%we make the value equal to 0 equal to the length of the data
find1xxxxa(find1xxxxa==0)=a;
find2xxxxa(find2xxxxa==0)=a;
find5xxxxa(find5xxxxa==0)=a;
find6xxxxa(find6xxxxa==0)=a;
find8xxxxa(find8xxxxa==0)=a;
find80xxxa(find80xxxa==0)=a;
find55xxxa(find55xxxa==0)=a;
find56xxxa(find56xxxa==0)=a;
find57xxxa(find57xxxa==0)=a;
find58xxxa(find58xxxa==0)=a;
find59xxxa(find59xxxa==0)=a;
find555xxa(find555xxa==0)=a;
%put the values of seksi3d according to where they should be
home = cell(a,12);
for i = 1:length(find1xxxx)
home{find1xxxxa(i),1} = seksi3d{find1xxxx(i)};
end
for i = 1:length(find2xxxx)
home{find2xxxxa(i),2} = seksi3d{find2xxxx(i)};
end
for i = 1:length(find5xxxx)
home{find5xxxxa(i),3} = seksi3d{find5xxxx(i)};
end
for i = 1:length(find55xxx)
home{find55xxxa(i),4} = seksi3d{find55xxx(i)};
end
for i = 1:length(find555xx)
home{find555xxa(i),5} = seksi3d{find555xx(i)};
end
for i = 1:length(find56xxx)
home{find56xxxa(i),6} = seksi3d{find56xxx(i)};
end
for i = 1:length(find57xxx)
home{find57xxxa(i),7} = seksi3d{find57xxx(i)};
end
for i = 1:length(find58xxx)
home{find58xxxa(i),8} = seksi3d{find58xxx(i)};
end
for i = 1:length(find59xxx)
home{find59xxxa(i),9} = seksi3d{find59xxx(i)};
end
for i = 1:length(find6xxxx)
home{find6xxxxa(i),10} = seksi3d{find6xxxx(i)};
end
for i = 1:length(find8xxxx)
home{find8xxxxa(i),11} = seksi3d{find8xxxx(i)};
end
for i = 1:length(find80xxx)
home{find80xxxa(i),12} = seksi3d{find80xxx(i)};
end
only need basic commands!
  1 Commento
dpb
dpb il 13 Giu 2022
Would have been much simpler to just clean the input instead...that would have been only a few lines of strrep calls. If didn't want to make the change permanent, wrap into another function and only fix internally to it; the original array would be unchanged.

Accedi per commentare.

Più risposte (1)

dpb
dpb il 7 Giu 2022
Modificato: dpb il 7 Giu 2022
criteria = [10000,20000,50000,55000,55500,56000,57000,58000,59000,80000];
rowcell={'10302','20245','50108','55112','58013','85911',[],[];
'10268',[],'55095','56099','58014','59944','81502',[];
'10308','20258','50054','55558','56019','83511',[],[];
'10307','20258','50073','55077','56018','56021','58162','83511';
'10325','20232','50082','55086',[],[],[],[];
'10276','20228',[],'56085','59013','81531',[],[]};
data=zeros(size(rowcell));
isC=cellfun(@ischar,rowcell);
data(isC)=cellfun(@str2num,rowcell(isC));
Out=nan(6,10);
for i=1:size(data,1)
ix=interp1(criteria,1:numel(criteria),data(i,:),"previous","extrap");
ix=ix(isfinite(ix));
Out(i,ix)=data(i,data(i,:)>0);
end
results in
end
>> Out
Out =
10302 20245 50108 55112 NaN NaN NaN 58013 NaN 85911
10268 NaN NaN 55095 NaN 56099 NaN 58014 59944 81502
10308 20258 50054 NaN 55558 56019 NaN NaN NaN 83511
10307 20258 50073 55077 NaN 56021 NaN 58162 NaN 83511
10325 20232 50082 55086 NaN NaN NaN NaN NaN NaN
10276 20228 NaN NaN NaN 56085 NaN NaN 59013 81531
>>
You can convert back to string or whatever form suits needs...to do with character strings is probably a fancy regexp() expression, but I'm not the one to even try it...
ADDENDUM:
Or, you can store the rowcell data into the output array as character instead of the numeric values directly if there's reason to keep that way instead --
Out=repmat({''},6,10); % array of empty cell char() strings
for i=1:size(data,1)
ix=interp1(criteria,1:numel(criteria),data(i,:),"previous","extrap");
ix=ix(isfinite(ix));
Out(i,ix)=rowcell(i,data(i,:)>0); % stuff the original char data in right column
end
which will return
>> Out
Out =
6×10 cell array
{'10302'} {'20245' } {'50108' } {'55112' } {0×0 char} {0×0 char} {0×0 char} {'58013' } {0×0 char} {'85911' }
{'10268'} {0×0 char} {0×0 char} {'55095' } {0×0 char} {'56099' } {0×0 char} {'58014' } {'59944' } {'81502' }
{'10308'} {'20258' } {'50054' } {0×0 char} {'55558' } {'56019' } {0×0 char} {0×0 char} {0×0 char} {'83511' }
{'10307'} {'20258' } {'50073' } {'55077' } {0×0 char} {'56021' } {0×0 char} {'58162' } {0×0 char} {'83511' }
{'10325'} {'20232' } {'50082' } {'55086' } {0×0 char} {0×0 char} {0×0 char} {0×0 char} {0×0 char} {0×0 char}
{'10276'} {'20228' } {0×0 char} {0×0 char} {0×0 char} {'56085' } {0×0 char} {0×0 char} {'59013' } {'81531' }
>>
NB: your original rowcell as defined will contain 0x0 double elements instead so you'll have mixed types to deal with when addressing.
The above is all char in cells; it could then actually be turned into a newfangled string array that just might be handy form to have...
>> string(Out)
ans =
6×10 string array
"10302" "20245" "50108" "55112" "" "" "" "58013" "" "85911"
"10268" "" "" "55095" "" "56099" "" "58014" "59944" "81502"
"10308" "20258" "50054" "" "55558" "56019" "" "" "" "83511"
"10307" "20258" "50073" "55077" "" "56021" "" "58162" "" "83511"
"10325" "20232" "50082" "55086" "" "" "" "" "" ""
"10276" "20228" "" "" "" "56085" "" "" "59013" "81531"
>>
Just all depends upon what the whole point of the exercise is down the road...
  2 Commenti
eko supriyadi
eko supriyadi il 7 Giu 2022
Modificato: eko supriyadi il 7 Giu 2022
many thanks for your help dbp.. when i'm trying with other matrix (attached), why i always getting notif in this step:
data(isC)=cellfun(@str2num,rowcell(isC));
the error is:
Error using cellfun
Non-scalar in Uniform output, at index 376, output 1.
Set 'UniformOutput' to false.
when i'm trying to change with:
data(isC)=cellfun(@str2num,rowcell(isC),'UniformOutput',false);
i'm still get error:
Conversion to double from cell is not possible.
edited:
Using with different data, the criteria maybe change become:
criteria = [{'1xxxx'},{'2xxxx'},{'5xxxx'},{'55xxx'},{'555xx'},{'56xxx'},{'57xxx'},{'58xxx'},{'59xxx'},{'6xxxx'},{'80xxx'},{'81xxx'},{'82xxx'},{'83xxx'},{'84xxx'},{'85xxx'},{'86xxx'},{'87xxx'},{'88xxx'},{'89xxx'}];
for antisipated the long row dataset
dpb
dpb il 7 Giu 2022
Couple of issues in that dataset doesn't match the assumptions made based on the example --
  1. It contains both [0x0 char] and [0x0 double] elements; the first step presumes all empty cells are the double;
  2. More troublesome is there are values that cannot be converted to numeric --
Working around the first, we change to look for empty and return "isNE", the indices that aren't empty--
isNE=~cellfun(@isempty,rowcell);
we then look for those elements that aren't convertible to numeric form --
isNNum=~cellfun(@(c)matches(c,digitsPattern),rowcell(isNE));
and select those to see what gives -- this is a two-step process; there's no syntax in MATLAB to "stack" indices
rcNE=rowcell(isNE);
rcNE(isNNum)
The result of the above is the following set--
>> rcNE(isNNum)
ans =
14×1 cell array
{'5796/'}
{'5796/'}
{'5790/'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
{'809//'}
>>
So, whassup w/ these? I presume it means some form of freeform number, but won't be able to use those for the lookup table approach with interp1 (which is a very neat trick, btw -- I've used the reverse lookup as here quite a number of times).
I've got meeting in town have to get cleaned up for and head that way, looks like you need to do some preprocessing on your data before applying the above; turn all the empty cells into one or the other of double or empty string; you'll have to deal with that dichotomy at some point or the other; either will/can be made to work, but handling both simultaneously will be a problem; I'd go w/ the double() because the later step is to select only the nonzero elements for the lookup; that's not so convenient if they're not numeric.
The second is to turn all the above into convertible numbers -- replacing the slashes with zeros would be the logical conversion.

Accedi per commentare.

Prodotti


Release

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by