0

ベクトルに一連のデータ ポイントがあります。例えば、

   [NaN, NaN, NaN, -1.5363, NaN -1.7664, -1.7475];

これらのデータは、指定された範囲 (具体的には -0.6 と 0.6) 内で 3 つのポイントを選択するコードから得られます。列の 3 つのポイントがこの範囲内に存在しない場合、範囲は 3 つのポイントが見つかるまで段階的に拡張されます。上記の例では、範囲が -1.8 ~ 1.8 に拡大されました。ただし、分析しているデータは不規則で、ランダムな山と谷があり、連続していないポイントが範囲に受け入れられます (要素 3 は有効として選択されますが、要素 4 は選択されません)。

これについて最善の方法は何ですか?範囲を段階的に増やして 3 点を見つけるコードが既にありますが、3 点で停止しないように変更する必要がありますが、3 つの CONTIGUOUS 点が見つかるまで範囲を拡大する必要があります。上記の例でそれが行われた場合、勾配を評価して 3 番目の要素を削除します (3 と 4 の間では勾配が負であるため)。

ありがとう。

4

1 に答える 1

0

例で提供されているデータが variable にあると仮定すると、次のようにandxを使用できます。isnanfindstr

x = [NaN, NaN, NaN, -1.5363, NaN -1.7664, -1.7475, 123];
~isnan(x)

ans =

 0     0     0     1     0     1     1     1

pos = findstr(~isnan(x), [1 1 1]);

このように使用する理由は、によって返される論理findstr配列内でシーケンスを検索し、このシーケンスが表示される入力配列内の位置のインデックスを返すためです。[1 1 1]isnanfindstr

サンプル データの場合、これは を返し[]ますが、私が示した例のデータに変更すると 6 が返され、 で連続領域を抽出できますx(pos:pos+2)[6 7]連続する値が 3 つ以上ある場合 (4 つある場合は を返します) や、連続する領域が複数ある場合には、少し注意が必要です。これらのケースで意味のあることをする必要がない場合は、単に pos(1) を使用してください。

長さが 3 以上の最初の連続した領域全体を抽出したい場合は、次のようにすることができます。

x = [NaN, NaN, NaN, -1.5363, NaN -1.7664, -1.7475, 123, 456, 789];

startPos = [];
stopPos = [];

pos = findstr(~isnan(x), [1 1 1]);
if ~isempty(pos)
    startPos = pos(1);
    stopPos = startPos + 2;

    % Find any cases where we have consecutive numbers in pos
    if length(pos) > 1 && any(diff(pos) == 1)
        % We have a contiguous section longer than 3 elements

        % Find the NaNs
        nans = find(isnan(x));
        % Find the first NaN after pos(1), or the index of the last element
        stopPos = nans(nans > startPos);
        if ~isempty(stopPos)
            stopPos = stopPos(1) - 1; % Don't want the NaN
        else
            stopPos = length(x);
        end
    end
end

x(startPos:stopPos)
于 2013-04-01T22:09:48.520 に答える