更新时间:2023-09-16 16:34:22
正如我在评论中提到的那样,您可能希望尝试使用一些大步小把戏.
As I mentioned in a comment, you may want to try using some stride tricks.
首先,让我们建立一个异常大小的数组:我们可以将其设置为np.int8
以节省空间
anomalies = x - x.mean()
signs = np.sign(anomalies).astype(np.int8)
现在大步向前.如果您要考虑N
个连续点,请使用
Now for the strides. If you want to consider N
consecutive points, you'll use
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
行将毫无意义,因此从现在开始,我们将使用
That gives us a (x.size, N)
rollin array: the first row is x[0:N]
, the second x[1:N+1]
... Of course, the last N-1
rows will be meaningless, so from now on we'll use
strided = strided[:-N+1]
我们沿行求和
Let's sum along the rows
consecutives = strided.sum(axis=-1)
这为我们提供了一个大小为(x.size-N+1)
的数组,其值在-N
和+N
之间:我们只需找出绝对值在N
处:
That gives us an array of size (x.size-N+1)
of values between -N
and +N
: we just have to find where the absolute values are N
:
(indices,) = np.nonzero(consecutives == N)
indices
是数组x
的索引i
的数组,其值x[i:i+N]
在均值的同一侧...
indices
is the array of the indices i
of your array x
for which the values x[i:i+N]
are on the same side of the mean...
带有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]),)