Avoid for loop: Looping through rows of m-by-n logical array

8 ビュー (過去 30 日間)
Zwithouta
Zwithouta 2018 年 4 月 20 日
編集済み: Zwithouta 2018 年 4 月 25 日
Postedit: Read the comments below the accepted answer!
Is it possible to view the rows of a logical array independently without using a for-loop?
x = randi(5, 1, 10) % create 1x10 vector containing random integers between 1 & 5
y = randi(5, 1, 10)
xVals = unique(x)' % get column-vector of unique values of x
tf = x == xVals % logical array, that shows for every unique x-value, at which indices it occurs in x.
for i = 1:size(tf,1) % loop through rows of logical array
yVals(i) = {y(tf(i,:))}; % Assign all y-values that belong to one xVal-entry to one cell.
end

採用された回答

Matt J
Matt J 2018 年 4 月 20 日
編集済み: Matt J 2018 年 4 月 20 日
[~,~,idx] = unique(x);
yVals=accumarray(idx,y,[],@(x){x(:).'}).'; 
  2 件のコメント
Zwithouta
Zwithouta 2018 年 4 月 20 日
編集済み: Zwithouta 2018 年 4 月 25 日

@ Matt J

Thanks for the answers, guys, but that's not exactly what I'm looking for. Let me ask my question better.

If you have a logical array a

a = logical([0 1 0
             0 1 1 
             0 0 1])

and a cell array b

b = [1 2 3
     4 5 6
     7 8 9]
b = mat2cell(b, [ones(1,3)], [ones(1,3)]);

Logical indexing will give the following output

b(a) 
ans =
4×1 cell array
  {[2]}
  {[5]}
  {[6]}
  {[9]}

That is, the information about which row & column the verified cells had in b is lost when you use logical indexing.

Is it possible to use logical indexing (not other methods, like accumarray) in a way, that it preserves this information? The output should then look like this

3×1 cell array
  {[2]}
  {[5,6]}
  {[9]}

After all, all information needed for this output is contained in the logical array, but is then kind of voluntarily dropped by Matlab.

Matt J
Matt J 2018 年 4 月 20 日
編集済み: Matt J 2018 年 4 月 20 日

After all, all information needed for this output is contained in the logical array, but is then kind of voluntarily dropped by Matlab.

Well, the logical array by itself doesn't have all the information. You need to tell MATLAB for example that each cell should contain row data and not column data. Otherwise, why couldn't {[2;5], [6;9]} be the result?

The closest thing giving what you are asking for would be the following, I think:

yVals=arrayfun(@(i) b(i,a(i,:)) , 1:size(b,1),'uni',0  ).'

This doesn't really avoid a for-loop however, except syntactically.

サインインしてコメントする。

その他の回答 (2 件)

Matt J
Matt J 2018 年 4 月 20 日
編集済み: Matt J 2018 年 4 月 20 日

Another way,

yVals = splitapply( @(g){g(:).'}, y, findgroups(x))

Bruno Luong
Bruno Luong 2018 年 4 月 21 日
編集済み: Bruno Luong 2018 年 4 月 21 日

For older MATLAB version, this FEX might be useful SplitVec

c = SplitVec(sortrows([x;y]'),1,2)

When stable ordering of y is desired

c = SplitVec(sortrows([x;y]',1),1,2)

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by