4

numpy / pandasを使用してSPC分析を行っています。

これの一部は、データ系列をネルソン ルールウェスタン エレクトリック ルールに照らしてチェックすることです。

例 (ネルソン ルールのルール 2): 連続する 9 つ (またはそれ以上) の点が平均の同じ側にあるかどうかを確認します。

これで、配列を反復処理することで、このようなルールのチェックを簡単に実装できるようになりました。

  • しかし、それを行う前に、numpy/pandas に反復なしでこれを行う方法があるかどうかをここで確認していますか?
  • いずれにせよ:上記のようなチェックを実装する「numpy-ic」の方法は何ですか?
4

4 に答える 4

2
import numpy as np
x = np.random.rand(100)
f = np.sign(x - x.mean())
c = np.cumsum(f)
d = c[9:] - c[:-9]
print np.max(d), np.min(d)

np.max(d) == 9 または np.min(d) == -9 の場合、連続して 9 つ (またはそれ以上) の点が平均の同じ側にあります。

または、次のコードを使用して、すべての行の長さを計算できます。

np.diff(np.where(np.diff(np.r_[-2,f,-2]))[0])
于 2012-09-11T13:27:44.277 に答える
1

コメントで述べたように、ストライドトリックを試してみることをお勧めします。

  • まず、異常のサイズの配列を作成しましょう。np.int8スペースを節約するために配置できます。

    anomalies = x - x.mean()
    signs = np.sign(anomalies).astype(np.int8)
    
  • さあ、歩みを進めましょう。N連続したポイントを検討したい場合は、

    from np.lib.stride_tricks import as_strided
    strided = as_strided(signs, 
                         strides=(signs.itemsize,signs.itemsize), 
                         shape=(signs.shape,N))
    

    これにより、(x.size, N)ロールイン配列が得られます。最初の行はx[0:N]、2番目の行ですx[1:N+1]...もちろん、最後のN-1行は無意味なので、これからは

    strided = strided[:-N+1]
    
  • 行に沿って合計しましょう

    consecutives = strided.sum(axis=-1)
    

    これにより、と(x.size-N+1)の間の値のサイズの配列が得られます。絶対値がどこにあるかを見つける必要があります。-N+NN

    (indices,) = np.nonzero(consecutives == N)
    

    indicesは、値が平均の同じ側にある配列のインデックスiの配列です。xx[i:i+N]

x=np.random.rand(10)との例N=3

>>> x = array([ 0.57016436,  0.79360943,  0.89535982,  0.83632245,  0.31046202,
            0.91398363,  0.62358298,  0.72148491,  0.99311681,  0.94852957])
>>> signs = np.sign(x-x.mean()).astype(np.int8)
array([-1,  1,  1,  1, -1,  1, -1, -1,  1,  1], dtype=int8)
>>> strided = as_strided(signs,strides=(1,1),shape=(signs.size,3))
array([[  -1,    1,    1],
       [   1,    1,    1],
       [   1,    1,   -1],
       [   1,   -1,    1],
       [  -1,    1,   -1],
       [   1,   -1,   -1],
       [  -1,   -1,    1],
       [  -1,    1,    1],
       [   1,    1, -106],
       [   1, -106,  -44]], dtype=int8)
>>> consecutive=strided[:-N+1].sum(axis=-1)
array([ 1,  3,  1,  1, -1, -1, -1,  1])
>>> np.nonzero(np.abs(consecutive)==N)
(array([1]),)
于 2012-09-11T23:58:19.973 に答える
1

別の可能性:相関または畳み込みを使用する

>>> a = np.random.randn(50)
>>> b = (a - a.mean()) > 0
>>> b.astype(int)
array([0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
       1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0,
       1, 1, 1, 1])

>>> c = np.correlate(b, np.ones(3), mode='valid')
>>> c
array([ 2.,  2.,  1.,  1.,  1.,  1.,  0.,  0.,  1.,  2.,  3.,  2.,  2.,
        1.,  1.,  0.,  0.,  1.,  2.,  3.,  3.,  3.,  3.,  3.,  2.,  2.,
        2.,  2.,  2.,  1.,  1.,  1.,  1.,  2.,  1.,  2.,  2.,  2.,  1.,
        0.,  0.,  1.,  2.,  2.,  2.,  2.,  3.,  3.])

>>> c.max() == 3
True
>>> c.min() == 0
True

HYRYcumsumバージョンより遅くなります。

余談ですが、同様の実行をテストするための実行テストがstatsmodelsにあります

于 2012-09-11T13:37:46.313 に答える
1

与えられたdata最小lengthの場合、配列かどうかを確認できます

np.diff(np.cumsum(np.sign(data - np.mean(data))), length)

ゼロを含みます。

于 2012-09-11T13:14:27.627 に答える