How can I arrange or matrix columns, depending on the total sum that has the columns?

7 vues (au cours des 30 derniers jours)
Hi, I need to arrange a matrix A to look like matrix B.
Matrix A generate new positions at every iteration, so the positions are not fixed.
If there is a column in A (in this case, column 3) that has sum=0, and after it has column that sum=1 (column 4), I want column 4 to move to column 3. Then column 5 move to column 4 and the last column is the one that keeps the sum=0 column.
This is a sequencing problem, so my desire is to have a smooth sequence.
What is the best way to do this?
Thanks!
if true
A = [0 1 0 0 0;
1 0 0 0 1;
0 0 0 1 0;
0 0 0 0 0;
0 0 0 0 0];
B = [0 1 0 0 0;
1 0 0 1 0;
0 0 1 0 0;
0 0 0 0 0;
0 0 0 0 0];
end

Réponse acceptée

Roger Stafford
Roger Stafford le 24 Mai 2014
Modifié(e) : Roger Stafford le 24 Mai 2014
Do
s = sum(A,1);
p = find(s(1:end-1)==0&s(2:end)==1);
B = A(:,[setdiff(1:size(A,2),p),p]);
(Corrected)
  2 commentaires
Patty
Patty le 24 Mai 2014
Thanks!! I tried, but it seems that only works for this example matrix.
I already wrote a small code that works fine. I share here for any body that might need someday.
Seq is a 3-D matrix. micro_period= number of columns
if true
newSeq=Seq;
for kk=1:Line
idx_zero=[];
idx_one=[];
for ii=1:micro_period
col_sum=sum(Seq(:,ii,kk));
if col_sum==0
idx_zero=[idx_zero;ii];
else
idx_one=[idx_one;ii];
end
end
for jj=1:length(idx_one)
newSeq(:,jj,kk)=Seq(:,idx_one(jj),kk);
end
for zz=1:length(idx_zero)
newSeq(:,length(idx_one)+zz,kk)=Seq(:,idx_zero(zz),kk);
end
end
Seq=newSeq;
end
Maybe its a little bit rustic haha, but it's working! :)
Roger Stafford
Roger Stafford le 25 Mai 2014
Patty, in your description you stated "If there is a column in A (in this case, column 3) that has sum=0, and after it has column that sum=1 (column 4), I want ...". However, the code you wrote never checks for a succeeding sum of one. To accomplish what your code does, you can just remove the test for a sum of 1 in the code I gave you:
s = sum(A,1);
p = find(s(1:end-1)==0);
B = A(:,[setdiff(1:size(A,2),p),p]);
It will always agree with the result you obtained.

Connectez-vous pour commenter.

Plus de réponses (1)

Image Analyst
Image Analyst le 24 Mai 2014
Patty: Here's an alternate way using sort() that I think does what you want:
% Generate random A.
A = randi(9, [20,6])
% Sum the columns.
sumA = sum(A, 1)
% Sort A in ascending order.
% The sortOrder is what we need here.
[sortedSums, sortOrder] = sort(sumA, 'Ascend')
% Make B sorted in order of increasing column sums of A.
B = A(:, sortOrder)
% Get sums of B to verify it worked
sumB = sum(B, 1)
A =
2 7 1 9 6 7
8 4 2 2 4 7
3 5 2 3 3 7
6 6 2 4 5 1
9 1 3 1 4 7
4 3 3 7 4 5
7 7 2 4 6 2
7 7 3 9 7 1
4 2 9 4 4 8
6 2 7 6 4 2
1 1 6 2 2 2
9 1 2 4 1 6
2 4 2 2 3 9
3 6 1 7 3 5
8 7 9 8 6 7
5 5 7 4 9 2
7 1 6 7 9 9
4 6 3 3 5 5
3 2 2 5 3 7
1 2 6 8 7 1
sumA =
99 79 78 99 95 100
sortedSums =
78 79 95 99 99 100
sortOrder =
3 2 5 1 4 6
B =
1 7 6 2 9 7
2 4 4 8 2 7
2 5 3 3 3 7
2 6 5 6 4 1
3 1 4 9 1 7
3 3 4 4 7 5
2 7 6 7 4 2
3 7 7 7 9 1
9 2 4 4 4 8
7 2 4 6 6 2
6 1 2 1 2 2
2 1 1 9 4 6
2 4 3 2 2 9
1 6 3 3 7 5
9 7 6 8 8 7
7 5 9 5 4 2
6 1 9 7 7 9
3 6 5 4 3 5
2 2 3 3 5 7
6 2 7 1 8 1
sumB =
78 79 95 99 99 100

Catégories

En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by