# How can I separate a sorted array into multiple at points referenced by another array?

조회 수: 1(최근 30일)
sma165 2021년 7월 30일
편집: Dave B 2021년 7월 30일
Say I have:
A = [1 4 7 9];
B = [0 2 3 5 6 8 10 11 12 13];
And I want to separate and organize the arrays as follows:
C{1} = [1 2 3];
C{2} = [4 5 6];
C{3} = [7 8];
C{4} = [9 10 11 12 13];
Any ideas how to efficiently do this?
I've done it with a for loop as such, but it's very slow as the real arrays are much larger:
for i = 1:length(A)-1
idx = A(i) > B & A(i+1)<= B;
C{i} = B(idx)';
end
C{:}
ans = 0×1 empty double column vector ans = 0×1 empty double column vector ans = 0×1 empty double column vector
ans = 1×5
9 10 11 12 13
##### 댓글 수: 1표시숨기기 없음
Matt J 2021년 7월 30일
I have edited your post to run your code within it. The result doesn't agree with what you say it produces.

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

### 채택된 답변

Matt J 2021년 7월 30일
This might be what you want:
A = [1 4 7 9];
B = [1 2 3 4 5 6 7 8 9 10 11 12 13];
G=discretize(B,[A,inf]);
C=splitapply(@(x) {x}, B,G);
C{:}
ans = 1×3
1 2 3
ans = 1×3
4 5 6
ans = 1×2
7 8
ans = 1×5
9 10 11 12 13

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

### 추가 답변(1개)

Dave B 2021년 7월 30일
편집: Dave B 2021년 7월 30일
The discretize function (or the third output of thie histcounts function) is good for this kind of problem (it'll do the > and <= for you), you can avoid a loop with arrayfun although I'm not sure it'll really be faster nor easier to read.
I adjusted your data slightly to capture to capture the case where there's a value in B that's bigger than the largest A, and your solution slightly as it didn't produce any results as written.
A = [1 4 7 9 13];
B = [0 2 3 5 6 8 10 11 12 13 15];
% original solution
for i = 1:length(A)-1
idx = B > A(i) & B <= A(i+1);
C{i} = B(idx)';
end
% Alternate solution
%[~,~,ind]=histcounts(B,A); % this returns which 'bin'
ind = discretize(B,A);
C2 = arrayfun(@(x){B(ind==x)'}, 1:numel(A)-1);
isequal(C,C2)
% note that B(1) and B(end) are not in any bin, histcounts reports these as
% B(ind==0), while discretize reports these as B(isnan(ind))
Alternatives to arrayfun here include accumarray/splitapply. The syntax of accumarray is not for the faint of heart, I only mention it because often when doing an operation like this youre next step is to 'do something' with the contents of each group...like take the average etc. So if that's where you're headed next you might consider it. splitapply is a more modern and friendlier version, and (if you're really after a summary statistic) groupsummary may be even easier!
accumarray(ind(ind>0)',B(ind>0)',[],@(x) {x})'
splitapply(@(x) {x},B(ind>0)',ind(ind>0)')'

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

R2018a

### Community Treasure Hunt

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

Start Hunting!