我试图解决这个问题:
我有一组数据点,对应于一组时间值。即values =[1,2,3,4,5,6,7,8,4] times = [0.1,0.2,0.3,0.4]...
等等,它的采样率为10hz。
我需要找到两个限制之间的时间。所以例如,如果我的限制是3和5,那么3,4,5,4是我的限制。
如果我将时间计算为(points -1) /sample rate
的数量,或者分组的开始时间和结束时间,我将错过孤立的数据点(第二个4)
我建议使用一半采样率的虚拟缓冲区来模拟孤立事件。
但是我在代码(python)中实现它时遇到了麻烦 我需要一种迭代点,计算点数的方法,配对能够执行(点数-1)/采样率。以及如何获取奇点并将缓冲值应用于点数。
我似乎无法找到if
和while
语句的正确组合来执行此操作。
答案 0 :(得分:1)
这是一个能够做你想要的功能。在指定限制内的多个数据点的运行被给予等于数据点的数量乘以采样周期的时间值(即采样频率的倒数),孤立的单个点被赋予采样周期的一半的值。
#!/usr/bin/env python
''' Estimate time of data points falling within specified limits
From http://stackoverflow.com/q/29430625/4014959
Written 2015.04.03 by PM 2Ring,
with help from Antti Haapala and Martijn Pieters
'''
from itertools import groupby
def estimate_time(values, lo_lim, hi_lim, sample_rate):
#Find values that are in range
in_range = [lo_lim <= v <= hi_lim for v in values]
#Find runs of in-range values
runs = [sum(1 for _ in group) for v, group in groupby(in_range) if v]
#Estimate total time spent in-range
total_time = sum(v if v > 1 else 0.5 for v in runs)
return total_time / sample_rate
values = [1, 2, 3, 4, 5, 6, 7, 8, 4]
sample_rate = 10.0 # in Hz
lo_lim = 3
hi_lim = 5
print estimate_time(values, lo_lim, hi_lim, sample_rate)
<强>输出强>
0.35
要检查此代码是否真的符合您的要求,您可以将一些打印语句放入estimate_time()
以显示in_range
和runs
的内容。
减少内存需求可以做的一件事是将列表推导转换为生成器表达式。列表推导必须在内存中创建一个全新的列表(一旦超出范围就被删除);生成器表达式稍慢,但它不需要构建列表 - 结果是在需要时生成的。语法非常相似 - 只需用圆括号替换list comp的方括号,将其转换为gen exp。
所以改变
in_range = [lo_lim <= v <= hi_lim for v in values]
到
in_range = (lo_lim <= v <= hi_lim for v in values)
和
runs = [sum(1 for _ in group) for v, group in groupby(in_range) if v]
到
runs = (sum(1 for _ in group) for v, group in groupby(in_range) if v)