pandas 不使用迭代的连续数据点推理

6qfn3psc  于 2023-02-27  发布在  其他
关注(0)|答案(4)|浏览(104)

我正在使用numpy/pandas执行SPC分析。
其中一部分是根据Nelson rulesWestern Electric rules检查数据系列。
例如(纳尔逊规则第2条):检查一行中是否有9个(或更多)点位于平均值的同一侧。
现在,我可以简单地通过迭代数组来实现对这样的规则的检查。

  • 但是在我这么做之前,我在这里检查一下,如果numpy/panda有办法不经过迭代就可以做到这一点?
  • 在任何情况下:实现上述检查的"numpy-ic"方法是什么?
4szc88ey

4szc88ey1#

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,则一行中有九个(或更多)点在平均值的同一侧。
或者您可以使用以下代码来计算每行的长度:

np.diff(np.where(np.diff(np.r_[-2,f,-2]))[0])
wnrlj8wa

wnrlj8wa2#

正如我在评论中提到的,你可能想尝试使用一些跨步技巧。

  • 首先,让我们创建一个异常大小的数组:我们可以将其设置为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) rollin数组:第一行是x[0:N],第二行是x[1:N+1] ...当然,最后的N-1行将没有意义,因此从现在开始我们将使用

strided = strided[:-N+1]
  • 让我们沿着行求和
consecutives = strided.sum(axis=-1)

这就给出了一个大小为(x.size-N+1)的数组,其值介于-N+N之间:我们只需要找到绝对值N的位置:

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

indices是数组x的索引i的数组,其值x[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]),)
6yoyoihd

6yoyoihd3#

给定data和最小值length,您可以检查数组是否

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

包含零。

zxlwwiss

zxlwwiss4#

另一种可能性:使用相关或卷积

>>> 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

它会比HYRY cumsum版本慢。
旁白:statmodels中有一个runstest用于测试类似的运行

相关问题