Operating on One Column Based on Another

So I've run into a buzzsaw of a problem. I have a m x n numeric matrix (no strings, etc.) and two columns are of interest. Column 1 looks like this:
A = [1;1;1;1;2;2;2;3;3;3;3;3;4;4;4;5;5;5]
Next, column 2:
B = [1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18];
What want to do is look at where values of A are equal and operate on those values in the same position in B. In other words, A(1:4) = 1 so I want to add together (or standard deviation, variance, etc.) B(1:4). Then, I want to move on to the next set of equal values of A and operate on the corresponding positions of B, and so on. Once values have been added together, I want to compare the result against a tolerance value and if the sum falls outside of the value, I want to delete those rows.
The problem I'm running into is that all of the comparison methods I've tried automatically dismiss the last value in B. So, where A(5:1) doesn't equal A(4:1), I'll get a sum, let's say, for B(1:3) instead of B(1:4). For example, one method I tried was:
a = unique(matrix(:,col_A))
tol = 5;
for i = 1:length(matrix)
idx = find(matrix(i,col_A) == a);
if isequal(matrix(i),idx)
std_dev = std(matrix(m,B));
if std_dev < tol
matrix(matrix(m,:)) = [];
end
end
end
At first, because of how isequal works, the algorithm discards A(4,1) doesn't equal A(5,1). I understand why this is happening, but I can't think of a viable solution. I tweaked it a bit, but now when I run the algorithm as written above, nothing happens at all.
If I was unclear at any point, don't hesitate to let me know. Any help you all can provide would be most appreciated!

 采纳的回答

You should look into accumarray:
>> A = [1;1;1;1;2;2;2;3;3;3;3;3;4;4;4;5;5;5];
>> B = [1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18];
>> S = accumarray(A,B,[],@sum)
S =
10
18
50
42
51
>> S(A)
ans =
10
10
10
10
18
18
18
50
50
50
50
50
42
42
42
51
51
51
If the values of A are not consecutive integers starting from one, then use unique first and use its third output argument.

3 个评论

Stephen - First, thank you very much for your reply. This looks like exactly what I need. Here's a follow-up question if you have time: these are the vectors I'm actually working with
A = [10517;10517;10517;10517;29272;29272;29272;29272;29272;35942; ...
35942;35942;35942;35942;39017;39017;39017;39017]
B = [-25;37;-34;69;-20;-21;-22;-23;-25;5;6;8;5;4;-17;-20;-25;-23]
In order to make things work, I had to rewrite A to be:
new_A = [1;1;1;1;2;2;2;2;2;3;3;3;3;3;4;4;4;4]
Leaving it in the original configuration produced a 39017x1 matrix of 0s, which was extremely unhelpful. Further, I had to hardcode new_A so things would work as advertised. Is there a clever way I can substitute values of new_A into A so I don't have to hardcode anything? Also, I wasn't following your advice regarding the use of the 'unique' function, so if that has an impact on things, I wouldn't know at this point.
Thanks a lot for your time and help!
[~,~,newA] = unique(A,'stable')
You are my new hero. That is perfect and I sincerely appreciate your time. Take care and have a good weekend!

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Logical 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by