I have the matrix a=[5 5 10 10 2 4 5],I want the result to be d=[5 1 2 7;10 3 4 0;2 5 0 0;4 6 0 0],
1 view (last 30 days)
Show older comments
I have the matrix
a=[5 5 10 10 2 4 5],
I want the result to be
d=[ 5 1 2 7;
10 3 4 0;
2 5 0 0;
4 6 0 0],
3 Comments
Answers (4)
Image Analyst
on 25 Nov 2013
How about this:
a=[5 5 10 10 2 4 5]
d = transforma(a); % Call transforma() in the main program.
function d = transforma(a)
d=[ 5 1 2 7;
10 3 4 0;
2 5 0 0;
4 6 0 0];
It meets all the criteria you've given.
4 Comments
Image Analyst
on 25 Nov 2013
There is once I defined it. Did you overlook the
function d = transforma(a)
statement where I defined it?
Sean de Wolski
on 25 Nov 2013
a=[5 5 10 10 2 4 5],
clear d;
[u,~,iy] = unique(a,'stable');
for ii = numel(u):-1:1
lhs = [u(ii) find(iy==ii).'];
d(ii,1:numel(lhs)) = lhs;
end
6 Comments
Sean de Wolski
on 26 Nov 2013
Edited: Sean de Wolski
on 26 Nov 2013
@Walter, I'd be curious to time bsxfun(...) against find. I agree that any opportunity for a bsxfun, it should be used just 'cuz it's awesome.
@IA, you know how silent we are on future features :)
@Yousef, I do see the duplicated 20 in column two above. But I don't know how you got it. Please give me full reproduction steps.
When I run something like the following, it passes as I expect:
a = randi(700,[1 10000]);
% a=[5 5 10 10 2 4 5],
clear d;
[u,~,iy] = unique(a,'stable');
for ii = numel(u):-1:1
lhs = [u(ii) find(iy==ii).'];
d(ii,1:numel(lhs)) = lhs;
end
T = matlab.unittest.TestCase;
import matlab.unittest.constraints.IsEqualTo
T.verifyThat(ismember(1:numel(a),d(:,2:end)),IsEqualTo(true(1,numel(a))));
T.verifyThat(nnz(d(:,2:end)),IsEqualTo(numel(a)));
Interactive verification passed.
Interactive verification passed.
Andrei Bobrov
on 26 Nov 2013
Edited: Andrei Bobrov
on 26 Nov 2013
[a1,b,c] = unique(a(:),'first')
[~,ii] = sort(b);
a1 = a1(ii);
c = ii(c);
n = max(histc(c,(1:max(c))'));
f1 = @(x){[x(:)',zeros(1,n-numel(x))]};
p = accumarray(c,(1:numel(c))',[],f1)
out = [a1, cat(1,p{:})];
or with Nan
[a1,b,c] = unique(a(:),'first')
[~,ii] = sort(b);
a1 = a1(ii);
c = ii(c);
idx = bsxfun(@times,1:numel(a),bsxfun(@eq,a1,a));
idx(idx==0) = nan;
ii = sort(idx,2);
out = [a1,ii(:,~all(isnan(ii)))];
0 Comments
Roger Stafford
on 27 Nov 2013
Edited: Roger Stafford
on 27 Nov 2013
Here's another version. Let a be your array and d be the desired result.
[u,t,q] = unique(a(:),'first','stable');
[q,p] = sort(q);
r = p;
n = size(p,1);
r(p) = (1:n)';
t = r(t);
r = cumsum(1-accumarray(t(2:end),diff(t),[n,1]));
d = [i.accumarray([q,r],p)];
0 Comments
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!