Find column number for every row in matrix

19 ビュー (過去 30 日間)
Chun Chi Wyman Chung
Chun Chi Wyman Chung 2023 年 3 月 15 日
編集済み: John D'Errico 2023 年 3 月 15 日
Hello,
I'm trying to extract the column number of the first positive value in a matrix for every row, without using any loops.
For instance
-1 4 1
1 -1 -1
-5 4 -1
I want the output column vector to be:
2
1
2
I've attempted using find(), but I cannot restrict it to when there are multiple positive values in the same row.

採用された回答

Stephen23
Stephen23 2023 年 3 月 15 日
編集済み: Stephen23 2023 年 3 月 15 日
M = [-1,4,1;1,-1,-1;-5,4,-1]
M = 3×3
-1 4 1 1 -1 -1 -5 4 -1
Method one: logical array, CUMSUM, and FIND:
X = M>=0;
Y = X&cumsum(X,2)==1;
[C,~] = find(Y.')
C = 3×1
2 1 2
Method two: NUM2CELL, ARRAYFUN, and FIND:
C = cellfun(@(v)find(v>=0,1,'first'),num2cell(M,2))
C = 3×1
2 1 2
Method three: CUMPROD and SUM:
C = 1+sum(cumprod(M<0,2),2)
C = 3×1
2 1 2
Method four: CUMPROD, ONES, and MTIMES:
C = 1+cumprod(M<0,2)*ones(size(M,2),1)
C = 3×1
2 1 2
Method five: CUMSUM and MAX:
[~,C] = max(cumsum(M>=0,2)==1,[],2)
C = 3×1
2 1 2
Method six: CUMMAX, SIGN, MIN, and SUM:
C = 1-sum(min(0,sign(cummax(M,2))),2)
C = 3×1
2 1 2
Method seven: FIND and ACCUMARRAY:
[R,C] = find(M>=0);
C = accumarray(R,C,[],@min)
C = 3×1
2 1 2
Method eight: is left as an exercise for the reader.

その他の回答 (4 件)

the cyclist
the cyclist 2023 年 3 月 15 日
Here is one way:
M = [-1 4 1;
1 -1 -1;
-5 4 -1];
[r,c] = find(M>0);
[~,j] = unique(r);
out = c(j)
out = 3×1
2 1 2

David Hill
David Hill 2023 年 3 月 15 日
a=[ -1 4 1
1 -1 -1
-5 4 -1];
A=(a>0)';
[b,d]=find(A);
[~,e]=unique(d);
b(e)
ans = 3×1
2 1 2

Les Beckham
Les Beckham 2023 年 3 月 15 日
編集済み: Les Beckham 2023 年 3 月 15 日
A = [ -1 4 1
1 -1 -1
-5 4 -1 ];
[row, col] = find(A > 0)
row = 4×1
2 1 3 1
col = 4×1
1 2 2 3
[~,idx,~] = unique(row, 'first')
idx = 3×1
2 1 3
col(idx)
ans = 3×1
2 1 2

John D'Errico
John D'Errico 2023 年 3 月 15 日
編集済み: John D'Errico 2023 年 3 月 15 日
Simple. One line.
A = randi([-5,5],[10,7])
A = 10×7
0 -2 -5 -1 -3 1 0 2 1 -5 5 5 5 -2 3 0 4 -5 -2 5 -2 -3 5 -5 1 3 5 0 5 4 -4 -3 4 -5 -1 4 1 -4 -1 -1 -3 -5 2 4 -1 0 -2 5 1 0 1 3 0 3 5 -5 3 4 -1 1 -1 1 2 -2 5 -4 -1 1 -3 -1
[~,col] = max(A > 0,[],2)
col = 10×1
6 1 1 2 1 1 1 2 1 2
Why does it work? A > 0 returns an array that is true (1) only when a number is positive.
Max returns the location of the first such element (among equal maxes) that it finds. And since the A>0 matrix is a boolean one, it is composed of only 0 and 1 elements.
Will this fail if there are no positive elements at all in a row? Well, yes. In that case, it will return 1 for those rows.
But that is true of almost any of the schemes suggested by others. If you want a scheme that will return perhaps a NaN for those rows where there were no positive elements, you could patch it by one more test. I'll regenerate a new matrix with only a few columns, but many negative elements, to insure at least one row will have all non-positive elements.
A = randi([-10,5],[10,3])
A = 10×3
-4 2 -8 -1 -3 -4 -6 5 -2 -5 -10 4 4 -1 2 -4 4 0 -2 -4 -4 -9 -9 -1 -7 3 2 3 3 -7
[~,col] = max(A > 0,[],2);
col(~any(A>0,2)) = NaN
col = 10×1
2 NaN 2 3 1 2 NaN NaN 2 1
As you can see, in this final result, rows {2,7,8} had no positive elements at all, so a NaN was generated for those rows.
Or, perhaps you don't want to see a NaN generated. What we might do here is to append an extra column, that is ALWAYS positive. This is a common trick one can employ.
[~,col] = max([A,ones(size(A,1),1)] > 0,[],2)
col = 10×1
2 4 2 3 1 2 4 4 2 1
So for a 3 column array, it returns the number 4 where there were NO positive elements.
In the end, it is important that you decide what to do when NO elements are positive in a row, as you should expect to see a bug in your code at some point.
  1 件のコメント
Les Beckham
Les Beckham 2023 年 3 月 15 日
編集済み: Les Beckham 2023 年 3 月 15 日
Except that it doesn't quite work. Row 3 has no positive elements, but this approach returns a 1 for that row.

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

カテゴリ

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

製品


リリース

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by