找到数组低于特定阈值的第一个索引(并保持低于一段时间)
Find the first index for which an array goes below a certain threshold (and stay below for some time)
设 A
为一维 numpy 数组、阈值 t
和 window 长度 K
。
如何找到最小索引 j
,使得 A[j:j+K] < t
?(即 A 第一次低于阈值 在宽度为 K) 的完整 window 上。
我已经尝试过(未完成)循环的事情,但它似乎远非最佳,我想也许有一个聪明的 "numpy way" 可以做到这一点。
旁注:我们想要测试在某个 window 长度 期间我们是否低于阈值 而不是 ponctual 值这一事实有助于避免 on/off/on/off/on/off 接近阈值的人工制品(另见 Hysteresis:"hysteresis is intentionally added to an electronic circuit to prevent unwanted rapid switching [...] compensate for contact bounce in switches, or noise in an electrical signal.")。
方法 #1
我们可以使用1D convolution
-
np.flatnonzero(np.convolve(A<t, np.ones(K,dtype=int))==K)[0]-K+1
想法是在与阈值比较后得到布尔数组,然后运行一个1D
卷积,内核长度与window
相同,填充1s
.这给了我们每次滑动的总和 window。所以,总和为 K
的所有 windows 就是我们要找的那些。使用 flatnonzero
获取有效 windows 的起始索引。最后,select第一个
方法 #2
与binary-erosion
-
from scipy.ndimage.morphology import binary_erosion
np.flatnonzero(binary_erosion(A<t, np.ones(K), origin=-(K//2)))[0]
这 运行 是一个长度与 window
相同的滑动内核,并侵蚀掉所有 windows 没有 window
长度 True
的内核按顺序,给我们留下有效的。同样,使用 flatnonzero
获取索引,最后使用 select 第一个。我们需要将 arg origin
与二进制侵蚀一起使用,这样我们 select 就开始了。
方法 #3
这是另一个发现岛屿的 -
# Get mask of valid elements with comparison against thresh
mask = np.r_[False,A<t,False]
# Get indices of starts and ends for the valid islands
idx = np.flatnonzero(mask[:-1] != mask[1:])
start,stop = idx[::2],idx[1::2]
# Get the island lengths and check for lengths >=K and mask start indices
# and select the first one among them
out = start[(stop - start)>=K][0]
设 A
为一维 numpy 数组、阈值 t
和 window 长度 K
。
如何找到最小索引 j
,使得 A[j:j+K] < t
?(即 A 第一次低于阈值 在宽度为 K) 的完整 window 上。
我已经尝试过(未完成)循环的事情,但它似乎远非最佳,我想也许有一个聪明的 "numpy way" 可以做到这一点。
旁注:我们想要测试在某个 window 长度 期间我们是否低于阈值 而不是 ponctual 值这一事实有助于避免 on/off/on/off/on/off 接近阈值的人工制品(另见 Hysteresis:"hysteresis is intentionally added to an electronic circuit to prevent unwanted rapid switching [...] compensate for contact bounce in switches, or noise in an electrical signal.")。
方法 #1
我们可以使用1D convolution
-
np.flatnonzero(np.convolve(A<t, np.ones(K,dtype=int))==K)[0]-K+1
想法是在与阈值比较后得到布尔数组,然后运行一个1D
卷积,内核长度与window
相同,填充1s
.这给了我们每次滑动的总和 window。所以,总和为 K
的所有 windows 就是我们要找的那些。使用 flatnonzero
获取有效 windows 的起始索引。最后,select第一个
方法 #2
与binary-erosion
-
from scipy.ndimage.morphology import binary_erosion
np.flatnonzero(binary_erosion(A<t, np.ones(K), origin=-(K//2)))[0]
这 运行 是一个长度与 window
相同的滑动内核,并侵蚀掉所有 windows 没有 window
长度 True
的内核按顺序,给我们留下有效的。同样,使用 flatnonzero
获取索引,最后使用 select 第一个。我们需要将 arg origin
与二进制侵蚀一起使用,这样我们 select 就开始了。
方法 #3
这是另一个发现岛屿的 -
# Get mask of valid elements with comparison against thresh
mask = np.r_[False,A<t,False]
# Get indices of starts and ends for the valid islands
idx = np.flatnonzero(mask[:-1] != mask[1:])
start,stop = idx[::2],idx[1::2]
# Get the island lengths and check for lengths >=K and mask start indices
# and select the first one among them
out = start[(stop - start)>=K][0]