numpy:累积“更大”运算

mon*_*n79 5 python numpy numpy-ufunc

我正在尝试编写一个函数来检测所有上升沿 - 向量中值超过特定阈值的索引。这里描述了类似的内容:Python上升/下降沿示波器式触发器,但我想添加滞后,这样触发器就不会触发,除非该值低于另一个限制。

我想出了以下代码:

import numpy as np

arr = np.linspace(-10, 10, 60)
sample_values = np.sin(arr) + 0.6 * np.sin(arr*3)

above_trigger = sample_values > 0.6
below_deadband = sample_values < 0.0
combined = 1 * above_trigger - 1 * below_deadband
Run Code Online (Sandbox Code Playgroud)

现在,在combined数组中1,原始值高于上限,-1原始值低于下限,0原始值介于两者之间:

>>> combined
array([ 1,  1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  1,  1,  1,  0,  0,
        1,  1,  1,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  1,  1,  1,
        0,  0,  1,  1,  1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  1,
        1,  0,  0,  1,  1,  1,  0, -1, -1])
Run Code Online (Sandbox Code Playgroud)

我的想法是使用一些聪明的函数来顺序处理这个向量,并用它们前面的任何非零值替换所有的零序列。那么问题就归结为简单地找出值从-1到 的变化位置1

我认为greater如果使用正确,该操作将实现此目的:-1编码为True1as False

  • True(“-1”)>-1 ) -> True("-1")
  • ( True("-1") > 1) ->False ("1")
  • ( True("-1") > 0) ->True("-1")
  • ( False("1") > -1) ->True ("-1")
  • ( False("1") > 1) ->False("1")
  • ( False("1") > 0) -> False("1")

但结果并不是我所期望的:

>>> 1 - 2 * np.greater.accumulate(combined)
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,  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,  1,  1,  1,  1,  1,  1,  1,  1])
Run Code Online (Sandbox Code Playgroud)

在这种情况下,该函数似乎greater无法正确地将布尔值与数值进行比较,即使它在标量或成对使用时工作正常:

>>> np.greater(False, -1)
True
>>> np.greater.outer(False, combined)
array([False, False,  True,  True,  True,  True,  True,  True,  True,
        True,  True, False, False, False, False, False, False, False,
       False, False, False,  True,  True,  True,  True,  True,  True,
        True,  True,  True, False, False, False, False, False, False,
       False, False, False,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True, False, False, False, False, False,
       False, False, False, False,  True,  True])
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?我在这里做错了什么吗,有什么办法解决这个问题吗?

或者,也许您可​​以建议另一种方法来解决这个问题?

谢谢。

bb1*_*bb1 2

我不确定问题np.greater.accumulate是什么(它似乎确实不像广告中那样表现),但以下应该有效:

import numpy as np
import numpy as np

arr = np.linspace(-10, 10, 60)
sample_values = np.sin(arr) + 0.6 * np.sin(arr*3)

above_trigger = sample_values > 0.6
below_deadband = sample_values < 0.0
combined = 1 * above_trigger - 1 * below_deadband

mask = combined != 0
idx = np.where(mask,np.arange(len(mask)),0)
idx = np.maximum.accumulate(idx)
result = combined[idx]

print(f"combined:\n {combined}\n")
print(f"result:\n {result}")
Run Code Online (Sandbox Code Playgroud)

它给:

combined:
 [ 1  1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  1  1  1  0  0  1  1  1  0 -1 -1 -1
 -1 -1 -1 -1 -1 -1  0  1  1  1  0  0  1  1  1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 -1  1  1  1  0  0  1  1  1  0 -1 -1]

result:
 [ 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 -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  1  1  1  1  1  1 -1 -1]
Run Code Online (Sandbox Code Playgroud)

那么值从-1跳到1的索引可以如下获得:

np.nonzero(result[1:] > result[:-1])[0] + 1
Run Code Online (Sandbox Code Playgroud)

它给:

array([12, 31, 49])
Run Code Online (Sandbox Code Playgroud)