クイックMATLAB質問。「m」のウィンドウで特定の数の要素「n」を選択するための最良/最も効率的な方法は何でしょうか。つまり、シーケンスの最初の50個の要素、次に要素10〜60、次に要素20〜70などを選択します。現在、私のシーケンスはベクター形式です(ただし、これは簡単に変更できます)。
編集:私が扱っているシーケンスは長すぎてRAMに保存できません。ウィンドウを作成してから、分析したいウィンドウを呼び出したり、別のコマンドを実行したりできるようにする必要があります。
クイックMATLAB質問。「m」のウィンドウで特定の数の要素「n」を選択するための最良/最も効率的な方法は何でしょうか。つまり、シーケンスの最初の50個の要素、次に要素10〜60、次に要素20〜70などを選択します。現在、私のシーケンスはベクター形式です(ただし、これは簡単に変更できます)。
編集:私が扱っているシーケンスは長すぎてRAMに保存できません。ウィンドウを作成してから、分析したいウィンドウを呼び出したり、別のコマンドを実行したりできるようにする必要があります。
50行n列のウィンドウ配列をメモリに格納するのに十分なRAMがありますか?その場合、ウィンドウを一度に生成してから、各列に処理を適用できます。
%# idxMatrix has 1:50 in first col, 11:60 in second col etc
idxMatrix = bsxfun(@plus,(1:50)',0:10:length(yourVector)-50); %'#
%# reshapedData is a 50-by-numberOfWindows array
reshapedData = yourVector(idxMatrix);
%# now you can do processing on each column, e.g.
maximumOfEachWindow = max(reshapedData,[],1);
Kerrekの答えを補完するために:ループでそれを行いたい場合は、次のようなものを使用できます
n = 50
m = 10;
for i=1:m:length(v)
w = v(i:i+n);
% Do something with w
end
問題の説明にわずかな問題があります。「シーケンスの最初の50個の要素を選択し、次に要素10〜60を選択する」と言います。ただし、これは要素の選択に変換されます。
配列は1つのインデックスを使用するため、MATLABではもちろん意味をなさないパターンに合わせるために、最初のシーケンスは0〜10にする必要があります。これに対処するために、以下のアルゴリズムはstartIndexと呼ばれる変数を使用して、シーケンスサンプリングを開始する要素を示します。
インデックス配列を作成することにより、ベクトル化された方法でこれを実現できます。各シーケンスの開始インデックスで構成されるベクトルを作成します。再利用のために、シーケンスの長さ、シーケンス開始間のステップサイズ、および最後のシーケンスの開始を変数として設定します。説明する例では、シーケンスの長さは50、ステップサイズは10、最後のシーケンスの開始は入力データのサイズとニーズによって異なります。
>> startIndex = 10; >> sequenceSize = 5; >> finalSequenceStart = 20;
いくつかのサンプルデータを作成します。
>> sampleData = randi(100、1、28) sampleData = 1列目から18列目 8 53 10 82 82 73 15 66 52 98 65 81 46 44 83 9 14 18 19列目から28列目 40 84 81 7 40 53 42 66 63 30
シーケンスの開始インデックスのベクトルを作成します。
>> sequenceStart = startIndex:sequenceSize:finalSequenceStart sequenceStart = 10 15 20
データ配列にインデックスを付けるためのインデックスの配列を作成します。
>> index = cumsum(ones(sequenceSize、length(sequenceStart))) インデックス= 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 >>インデックス=インデックス+repmat(sequenceStart、sequenceSize、1)-1 インデックス= 10 15 20 11 16 21 12 17 22 13 18 23 14 19 24
最後に、このインデックス配列を使用してデータ配列を参照します。
>> sampleData(index) ans = 98 83 84 65 9 81 81 14 7 46 18 40 44 40 53
次のベクトル化されたコードについて考えてみます。
x = 1:100; %# an example sequence of numbers
nwind = 50; %# window size
noverlap = 40; %# number of overlapping elements
nx = length(x); %# length of sequence
ncol = fix((nx-noverlap)/(nwind-noverlap)); %# number of sliding windows
colindex = 1 + (0:(ncol-1))*(nwind-noverlap); %# starting index of each
%# indices to put sequence into columns with the proper offset
idx = bsxfun(@plus, (1:nwind)', colindex)-1; %'
%# apply the indices on the sequence
slidingWindows = x(idx)
結果(簡潔にするために切り捨て):
slidingWindows =
1 11 21 31 41 51
2 12 22 32 42 52
3 13 23 33 43 53
...
48 58 68 78 88 98
49 59 69 79 89 99
50 60 70 80 90 100
実際、このコードは、Signal Processing Toolboxの廃止されたSPECGRAM関数から採用されました(edit specgram.m
コードを確認するために行ってください)。
スライドウィンドウがシーケンス全体を均等に分割しない場合に備えて、シーケンスをゼロパッドする部分を省略しました(たとえばx=1:105
)が、その機能が必要な場合は、簡単に再度追加できます...
(start : step : end)
インデックス付け:v(1:1:50)
、v(10:1:60)
などを使用します。がの場合step
は1
、省略できます:v(1:50)
。