我正在处理一些结构如下的海潮数据:
$data = array('date' => array('time' => array('predicted','observed')));
以下是我正在使用的实际数据示例:http://pastebin.com/raw.php?i=bRc2rmpG
这是我尝试找到高/低值:http://pastebin.com/8PS1frc0
我的代码的当前问题:
11/14/2010=>11:30:00
到11/14/2010=>11:54:00
范围所示),它会在方向逻辑中产生“摆动”。这会产生错误的峰值和谷值。我该如何避免/纠正这个?注意:我的方法非常“特别”..我认为我不需要任何令人敬畏的数学东西,因为我不想找到任何平均值,近似值或未来的估计值。我真的很感谢一个更好的方法的代码示例,即使它意味着抛弃我到目前为止编写的代码。
答案 0 :(得分:2)
我必须在嘈杂的生理数据上执行类似的任务。在我看来,你有一个信号调节问题。这是一个对我有用的过程。
答案 1 :(得分:2)
我想要寻找当地的最小值和最大值?这很容易做到:
<?php
$data = array(1, 9, 4, 5, 6, 9, 9, 1);
function minima($data, $radius = 2)
{
$minima = array();
for ($i = 0; $i < count($data); $i += $radius)
{
$minima[] = min(array_slice($data, $i, $radius));
}
return $minima;
}
function maxima($data, $radius = 2)
{
$maxima = array();
for ($i = 0; $i < count($data); $i += $radius)
{
$maxima[] = max(array_slice($data, $i, $radius));
}
return $maxima;
}
print_r(minima($data));
print_r(maxima($data));
?>
您只需指定搜索半径,它将返回一组本地最小值和数据的最大值。它以一种简单的方式工作:它将数组切割成长度为$radius
的段,并找到该段的最小值。对整个数据集重复此过程。
小心半径:通常,您希望选择半径作为数据从峰到谷的平均距离,但您必须手动查找。它默认为2
,并且只搜索半径为2
的最小值/最大值,这可能会对您的数据集产生误报。 明智地选择半径。
你必须将它破解到你的脚本中,但这根本不应该太难。
祝你好运!答案 2 :(得分:1)
我没有详细阅读,但你的方法看起来非常特别。一种更正确的方法可能是将其适合函数
f(A,B,w,p;t)=Asin(wt+p)+B
使用诸如non-linear least squares之类的方法(遗憾的是必须使用迭代方法解决)。查看您的示例数据,看起来它很合适。当你计算了w和p时,只需要取函数的时间导数并求零即可轻松找到峰和谷:
t = (pi(1+2n)-2p)/w
但我想,如果你的代码确实能达到你想要的效果,那么就没有必要使事情复杂化。不要再猜测自己了。 :)
答案 3 :(得分:1)
问题是我认为观察结果是观察结果并且可能包含小错误。至少需要考虑到这一点。例如:
如果至少接下来的两个条目也在同一个方向,则只改变方向。
不要让差异太小的数据做出决定。扔掉微不足道的数字。当你说$error = 0.10;
并将你的条件改为if $previous - $error > $current
等等时,它会好很多。
答案 4 :(得分:0)
峰值/谷值检测的准确度如何?如果您只是需要找到峰值或谷值出现的确切记录,那么检查拐点是不够的?
e.g。考虑到位置'i'的记录,如果记录[i-1]和记录[i + 1]都比记录[i]“更高”,那么你就有了一个山谷。如果记录[i-1]和记录[i + 1]都低于记录[i],你就有了一个高峰。只要您的采样率快于潮汐变化(查找Nyquist frequency),该过程就可以获得数据的峰值/谷值。
如果您需要从中生成图表并尝试为峰值/波谷推断更准确的时间点,那么您需要做更多的工作。
答案 5 :(得分:0)
一种方法可能是定义绝对或相对偏差,您可以将其他峰值/谷值分类为新的峰值/谷值,而不是现有峰值/谷值周围的波动。
目前,$direction
确定您是在寻找峰值还是谷值,因此一旦衍生物在符号中发生变化,您就可以考虑更改状态,而不是转换到另一个状态(找到波谷或峰值)与当前峰值/谷值的偏差“足够大”。
答案 6 :(得分:0)
鉴于你不应该在不到12小时内看到两个最大值或2分钟,一个简单的解决方案是使用3-5小时左右的滑动窗口并找到最大值和最小值。如果它最终是在第一个或最后30分钟,请忽略它。
举个例子,给出以下数据:
1 2 3 4 5 6 5 6 7 8 7 6 5 4 3 2 1 2
和一个大小为8的窗口,第一个和最后一个被忽略,只看一眼你会看到:
1 2 | 3 4 5 6 | 5 6, max = 6, ignore = Y
2 3 | 4 5 6 5 | 6 7, max = 7, ignore = Y
3 4 | 5 6 5 6 | 7 8, max = 8, ignore = Y
4 5 | 6 5 6 7 | 8 7, max = 8, ignore = Y
5 6 | 5 6 7 8 | 7 6, max = 8, ignore = N
6 5 | 6 7 8 7 | 6 5, max = 8, ignore = N
5 6 | 7 8 7 6 | 5 4, max = 8, ignore = N
6 7 | 8 7 6 5 | 4 3, max = 8, ignore = N
7 8 | 7 6 5 4 | 3 2, max = 8, ignore = Y
8 7 | 6 5 4 3 | 2 1, max = 8, ignore = Y
7 6 | 5 4 3 2 | 1 2, max = 7, ignore = Y