在 Numpy 数组中提取高于特定阈值的连续值
Extracting continuous values above a certain threshold in a Numpy array
对于一个学校项目,我需要实现以下功能:
创建一个函数 find_intervals(s, threshold)
,在输入中接收一个系列 s 和一个阈值。
找出信号高于给定阈值时的连续周期。
该函数应该 return 一个系列,该系列具有每个连续期间的开始日期作为索引,并且具有以天数表示的期间长度作为关联值。结果应按周期长度降序排列。
当应用于这样的信号时(thershold=0 的橙色线):
它应该return以下系列:
70 35
140 35
1 34
Name: interval, dtype: int64
也就是说,最大的间隔是35个单位,它从标签70开始,然后还有另一个长度为35的间隔,从140开始,等等。在练习中,索引将是一个日期和长度间隔以天数表示。
我写了下面的函数(在this Whosebug answer的帮助下)
def intervals(samples,threshold):
samples = np.array(samples)
start = -1
intervals = []
for idx,x in enumerate(samples):
if start < 0 and abs(x) < threshold:
start = idx
elif start >= 0 and abs(x) >= threshold:
dur = idx-start
if dur >= 0:
intervals.append((start))
start = -1
return intervals
但是,当我在类似的正弦波上调用这个函数时,该函数对阈值 0 或任何负值不起作用。我真的不明白为什么。
编辑:这是我的尝试和得到的结果;
在下面的部分中,我绘制了一个简单的 Sin 波。
x = np.arange(0,64*np.pi,1)
y = np.sin(x/11)
df = pd.Series(data=y,index=x)
plt.plot(x,y)
df = np.array(df)
当我 运行 带有 intervals(df,0.5)
的代码时,我得到
[0, 34, 69, 103, 138, 172]
这是预期的。
但是;
如果我这样做; intervals(df,0)
我得到一个空列表,对于任何负阈值都可以说同样的事情。
将您的函数更改为:
def find_intervals2(samples, threshold):
samp = samples[samples >= threshold]
xx = samp.groupby((samp.index != samp.index.to_series().shift() + 1)
.cumsum()).apply(lambda grp: (grp.index[0], grp.size))
return pd.Series(xx.str[1].values, index=xx.str[0]).sort_values(ascending=False)
请注意,结果是 Series 而不是 list。
为了提供一个更具指导意义的示例,将源系列定义为:
x = np.arange(0, 68 * np.pi, dtype=int)
y2 = np.sin(x / 11 * (1000 - x) // 7 / 142)
s2 = pd.Series(data=y2, index=x)
plt.plot(s2)
plt.grid(True);
注意图中“逐步降低”的频率。
那么当你 运行 find_intervals(s2, -0.2)
结果是:
162 52
72 48
0 39
dtype: int64
对于一个学校项目,我需要实现以下功能:
创建一个函数 find_intervals(s, threshold)
,在输入中接收一个系列 s 和一个阈值。
找出信号高于给定阈值时的连续周期。
该函数应该 return 一个系列,该系列具有每个连续期间的开始日期作为索引,并且具有以天数表示的期间长度作为关联值。结果应按周期长度降序排列。
当应用于这样的信号时(thershold=0 的橙色线):
它应该return以下系列:
70 35
140 35
1 34
Name: interval, dtype: int64
也就是说,最大的间隔是35个单位,它从标签70开始,然后还有另一个长度为35的间隔,从140开始,等等。在练习中,索引将是一个日期和长度间隔以天数表示。
我写了下面的函数(在this Whosebug answer的帮助下)
def intervals(samples,threshold):
samples = np.array(samples)
start = -1
intervals = []
for idx,x in enumerate(samples):
if start < 0 and abs(x) < threshold:
start = idx
elif start >= 0 and abs(x) >= threshold:
dur = idx-start
if dur >= 0:
intervals.append((start))
start = -1
return intervals
但是,当我在类似的正弦波上调用这个函数时,该函数对阈值 0 或任何负值不起作用。我真的不明白为什么。
编辑:这是我的尝试和得到的结果;
在下面的部分中,我绘制了一个简单的 Sin 波。
x = np.arange(0,64*np.pi,1)
y = np.sin(x/11)
df = pd.Series(data=y,index=x)
plt.plot(x,y)
df = np.array(df)
当我 运行 带有 intervals(df,0.5)
的代码时,我得到
[0, 34, 69, 103, 138, 172]
这是预期的。
但是;
如果我这样做; intervals(df,0)
我得到一个空列表,对于任何负阈值都可以说同样的事情。
将您的函数更改为:
def find_intervals2(samples, threshold):
samp = samples[samples >= threshold]
xx = samp.groupby((samp.index != samp.index.to_series().shift() + 1)
.cumsum()).apply(lambda grp: (grp.index[0], grp.size))
return pd.Series(xx.str[1].values, index=xx.str[0]).sort_values(ascending=False)
请注意,结果是 Series 而不是 list。
为了提供一个更具指导意义的示例,将源系列定义为:
x = np.arange(0, 68 * np.pi, dtype=int)
y2 = np.sin(x / 11 * (1000 - x) // 7 / 142)
s2 = pd.Series(data=y2, index=x)
plt.plot(s2)
plt.grid(True);
注意图中“逐步降低”的频率。
那么当你 运行 find_intervals(s2, -0.2)
结果是:
162 52
72 48
0 39
dtype: int64