필터 지우기
필터 지우기

Assigning array values to cell array based on condition

조회 수: 11 (최근 30일)
Dominik Rhiem
Dominik Rhiem 2021년 12월 13일
댓글: Dominik Rhiem 2021년 12월 21일
I have two equally-sized vectors of indices like the following:
A = [1, 1, 1, 2, 2, 3, 3, 3, 3];
B = [6, 3, 7, 4, 7, 13, 16, 4, 1];
I want to assign the values of B into cell arrays based on the value of A at the same index, i.e.:
C{1} = B(A==1);
C{2} = B(A==2);
C{3} = B(A==3);
In reality, A contains all integers from 1 to 1600 (monotonically increasing, but each integer appears a different number of times), so it is impractical to write all lines out. So far, I have solved this with a loop (in each iteration, I create the mask C = B(A==iteration)), but loops are inefficient, so are there better ways to do it?
Similarly, I want to use this to assign values to the elements of a vector v. For example:
v(1) = sum(M(C{1}));
v(2) = sum(M(C{2}));
Where M is some other large vector from which we select the relevant entries by the indices in C as indicated. Again, this is currently implemented as a loop (i.e. v(i) = sum(M(B(A==i))) ), which works, but again, are there better ways to do it?

채택된 답변

Stephen23
Stephen23 2021년 12월 13일
편집: Stephen23 2021년 12월 13일
A = [1,1,1,2,2,3,3,3,3];
B = [6,3,7,4,7,13,16,4,1];
C = accumarray(A(:),B(:),[],@(v){v});
C{:}
ans = 3×1
6 3 7
ans = 2×1
4 7
ans = 4×1
13 16 4 1
For the second part of your question I would skip the cell array entirely:
M = randi(9,1,20);
V = accumarray(A(:),M(B(:)),[],@sum)
V = 3×1
15 9 17
  댓글 수: 2
Dominik Rhiem
Dominik Rhiem 2021년 12월 14일
편집: Dominik Rhiem 2021년 12월 15일
This is great, thank you. There is still one issue though: In one instance, I want to use accumarray to first take the logarithm of selected elements of a vector and then take the sum of those elements. However, some entries of that vector are 0, meaning after taking the logarithm they are at -Inf (we later take the exponential so that the result is 0 again). This was fine in the 'loop version' because Log would simply return -Inf (meaning after the sum and taking the exponential, we end up with 0 again), however, with accumarray, I get the following error: The function 'log' returned a non-scalar value. How can I solve this issue?
edit: Nevermind, I got it. First took the log of the whole thing and then the sum of the selected elements.
Dominik Rhiem
Dominik Rhiem 2021년 12월 21일
Hi, if you don't mind, I have a follow-up question. What if M and v are now matrices, not vectors, where I want to do the operation described above column-wise? I.e.:
v(:,1) = accumarray(A(:), v(B(:),1), [], @sum);
v(:,2) = accumarray(A(:), v(B(:),2), [], @sum);
Again, currently, I solved this with a loop, but more efficiency would be nice.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

태그

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by