我有一个看起来像这样的数据集(1D python列表):
[0,0,0,0,4,5,6,6,4,0,0,0,0,0,0,2,0,0,0,6,4,5,6,0,0,0,0,0]
我正在尝试根据上一个窗口找到变体的截止点。
我正在寻找输出:
[4, 9, 19, 23]
假设我的窗口必须至少为3,那么至少对于连续3个元素和数据中的一些噪声必须发生变化,我想出了:
有更好的方法可以做到这一点,还是内置的numpy功能来帮忙?
感谢。
@qwwqwwq提出的解决方案运行良好,但我有另一个小约束 - 我意识到我的列表值没有相同的权重。假设这个新数据集:
[(10, 0), (20, 0), (15, 0), (20, 0), (8, 4), (10, 5), (15, 6), (15, 6), (10, 4), (5, 0),(5, 0), (20, 0), (10, 0), (8, 0),(5, 0), (10, 2), (5, 0), (5, 0), (5,0), (10,6) ,(5, 4), (5,5), (10, 6), (10, 0),(10,0) ,(10,0) ,(10,0) ,(10,0)]
如何用最短时间替换widths = np.array([2]
?
我知道我可以slope_down_begin_points
,检查最近的slope_down_begin_points
并查看两者之间的点数之和是否为>最短时间。我对signal
不太熟悉,希望有更好的东西吗?
另一种更简单,更天真的方法是将> 0值组合在一起,并将[0]和[-1]值切成边缘。
for k, g in groupby(x, key=lambda v: v[1] == 0):
print k,g
group = list(g)
# only consider if long enough
if sum([z[0] for z in group]) > some_minumum_time:
# do stuff
答案 0 :(得分:1)
我能想到的最好的方法是将样条拟合到数组,取导数,然后找到所有局部最大值。这些局部最大值应该代表峰的边界,我认为这就是你所追求的。我的方法:
from scipy import signal
from scipy import interpolate
import numpy as np
from numpy import linspace
x = [0,0,0,0,4,5,6,6,4,0,0,0,0,0,0,2,0,0,0,6,4,5,6,0,0,0,0,0]
s = interpolate.UnivariateSpline( linspace(0,len(x)-1,len(x)), np.array(x) )
ds = s.derivative()
slope_down_begin_points = [ p for p in signal.find_peaks_cwt( vector = [ -ds(v) for v in range(len(x)) ], widths = np.array([2]) ) if x[p-1] >= 1 ]
slope_up_begin_points = [ p for p in signal.find_peaks_cwt( vector = [ ds(v) for v in range(len(x)) ], widths = np.array([2]) ) if x[p+1] >= 1 ]
slope_up_begin_points + slope_down_begin_points
>> [4, 9, 16, 19, 23]
16
包含在此方法中,因为它本身就是一个微小的峰值,如果您使用find_peaks_cwt
/ UnivariateSpline
参数,您应该能够将其过滤掉..