2012-01-18 9 views
1

で固定された最初と最後の要素を持つ行列の行私は、次の(任意のcols /行)のような行列を持つ:Matlabの:検索ベクトル

1 0 0 0 0 
1 2 0 0 0 
1 2 3 0 0 
1 2 3 4 0 
1 2 3 4 5 
1 2 5 0 0 
1 2 5 3 0 
1 2 5 3 4 
1 4 0 0 0 
1 4 2 0 0 
1 4 2 3 0 
1 4 2 5 0 
1 4 2 5 3 
1 4 5 0 0 
1 4 5 3 0 
2 0 0 0 0 
2 3 0 0 0 
2 3 4 0 0 
2 3 4 5 0 
2 5 0 0 0 
2 5 3 0 0 
2 5 3 4 0 
3 0 0 0 0 
3 4 0 0 0 
3 4 2 0 0 
3 4 2 5 0 
3 4 5 0 0 

、今、私はどこの最初の要素のすべての行を取得したいです特定の値Xであり、最後の要素(つまり最後の要素!= 0)は特定の値Y、ORは反転します。最初はY、最後はXです。

forループは使用しません。( ありがとう!

EDIT:特定の最初の要素を含むすべての行をフィルタリングするのは簡単ですが、ここで私を助ける必要はありません。それでは、私は次の操作を実行したいとしましょう:最後の要素(!各行のつまり最後の要素は、= 0)すべての行をフィルターXまたはYのいずれかである

EDITあなたの記事のための おかげで多くのことを。私は473408 * 10要素の行列で3つの可能な解をベンチマークしました。ここでbenchmarkscriptだ: http://pastebin.com/9hEAWw9a

結果は以下の通りであった。

t1 = 2.9425 Jonas 
t2 = 0.0999 Brendan 
t3 = 0.0951 Oli 

ので、おかげでたくさんの皆さん、私はオリのソリューションに固執ので、それを受け入れますよ。しかし、他のすべてのソリューションにも感謝します!

答えて

2

ここにありますトリック:右側に0で数字を探し、それらすべてを合計:

H=[1 2 0 0 0; 
    2 3 1 0 0; 
    4 5 8 0 0; 
    8 5 4 2 2]; 

lastNumber=sum(H.*[H(:,2:end)==0 true(size(H,1),1)],2) 

ans = 

    2 
    1 
    8 
    2 

残りは簡単です:

firstNumber=H(:,1); 

find((firstNumber==f) & (lastNumber==l)) 
+0

終わりの前にゼロがあれば失敗するでしょうが、いい考えです。 +1とにかく – Jonas

+0

@ジョナス:あなたはブレンダンの解決のような意味ですか?実際には、私はブレンドの投稿にコメントしたように、これは問題ではありません。なぜなら、実際にはリコール終了時には唯一のゼロがあるからです。 – tim

+0

@Oli:Thanks Oli、これもかなりいいです!最初の投稿で私の編集を見て、そこにベンチマークスクリプトとあなたのスクリプトが勝つ(:したがって私は受け入れた! – tim

5

すべての行の最後の非ゼロ要素の線形インデックスを見つけるだけです。残りは簡単です:

[nRows,nCols] = size(A); 
[u,v] = find(A); %# find all non-zero elements in A 
%# for each row, find the highest column index with accumarray 
%# and convert to linear index with sub2ind 
lastIdx = sub2ind([nRows,nCols],(1:nRows)',accumarray(u,v,[nRows,1],@max,NaN)); 

行をフィルタするには、あなたがして

goodRows = A(:,1) == X & A(lastIdx) == Y 
+0

T帽子はいいね、ありがとう。私は明日それをテストし、あなたに言うより! 'sub2ind()'について知りませんでしたので、私に頭痛を与えてしまったでしょう:)しかし、もしそれが分かっていれば、簡単かもしれません。今までありがとう!編集:また、 'accumarray'も知りませんでした:) – tim

+0

@ColHeather:accumarrayは当初理解するのが少し複雑ですが、それは非常に便利です。 – Jonas

+1

私の解決策がない場合でもこれは動作します。 'accumarray'を読む必要があります... – Brendan

1

を書くことができますこれは、各行における場合のみ数字が続く一連の非ゼロのx数ある作品ゼロ。以下は1 0 3 4 0 0可能であるならば、それは動作しません。つまり、私はそれはあなたが与えたサンプル入力に基づいて可能ではないと仮定し...

% 'a' is your array 
[nx, ny] = size(a); 
inds = [0:ny:ny*(nx-1)]' + sum(a ~= 0, 2); 
% Needs to transpose so that the indexing reads left-to-right 
aT = a'; 
valid1 = aT(inds) == Y; 
valid2 = a(:,1) == X; 
valid = valid1 & valid2; 
valid_rows = a(valid,:); 

これは私が知っている汚いです...

+0

はい、最後には0だけありますように、uは言った:)これも明日、今までありがとう! – tim

+0

ありがとうブレンダン、それは私にとってかなりうまくいく。ベンチマークのために上記の私の編集を見てください:-)あなたはかなりOliの解決策に近いです。:) – tim