【问题标题】:Get local min and max values from data array从数据数组中获取局部最小值和最大值
【发布时间】:2011-11-07 23:37:58
【问题描述】:

我有一个日期/某种值数组。当我把它画成图表时,它看起来像这样:

我想找到它的本地最小和最大点。我在上面的图表上用蓝点签署了它们。

.net/linq/c#/f# 中是否有任何内置支持来获取数组/列表的本地最小最大值?我用谷歌搜索了这个主题。我只是想在自己编码之前和重新发明轮子之前仔细检查一下。

请。检查我的示例图表和上面的蓝点,这不仅仅是从数组中获取最小最大值!

【问题讨论】:

  • local min and max 是什么意思?
  • "local" 可以表示任意数量的东西。您必须定义您的标准,然后编写代码来识别这些点。 “检查我的蓝点”并没有告诉我们太多。您想要某个 X 值范围内的最小和最大 Y 值吗?或者您是否在寻找拐点之间的最小值和最大值?如果您的标准没有一个好的定义,我们就无法给出一个好的答案。
  • @Tom,我看到了蓝点,但仍然不明白你的意思。你能解释一下吗?
  • 可能更清楚一点:这些数据来自机器并基于其操作,为了简单起见,可以将其称为“机器的燃料水平”,因此我的数据燃料水平与时间的关系。所以,数据频率取决于它的运行,如果它工作,我每 5 秒有一次数据,如果它不起作用,我每天有一次这个数据。我必须找到加油到机器的点,然后那里的燃料被偷了。
  • 所以您真正要寻找的是拐点。在您的情况下,只要机器中的燃料量增加,您就可以肯定地说添加了燃料。如果燃料量在短时间内减少了超过某个定义值(即,这个东西每小时燃烧 5 加仑,但在一分钟内损失了一加仑),那么燃料很可能被盗了。您想要的是确定随时间变化超过预期值的点。

标签: c# .net arrays list f#


【解决方案1】:

.NET(或 F# 库)中没有内置函数可以自动执行此操作。

给你一些初步的想法 - 如果你只有精确的数据(即忽略图表中的小峰值),那么在 F# 中很容易解决这个问题,这样数组中没有两个后续值是相同的。

在这种情况下,您可以通过查找三个以下值来找到最小值,使得中间值小于前一个值并且也小于下一个值。这会检测如下形状:

__  __
  \/

例如,如果你有 values 包含你的数据,你可以写:

let values = [ 1.0; 2.0; 1.5; 1.0; 4.0; 2.0 ]
// Add indices as the first element of a tuple (so that we can identify positions)
let valuesIndexed = values |> Seq.mapi (fun i v -> i, v)

// Use 'windowed' to create sliding window of size 3 and then 'choose'
// indices where previous value and following value are both larger
let mins = 
  valuesIndexed |> Seq.windowed 3 |> Seq.choose (fun arr ->
    match arr.[0], arr.[1], arr.[2] with
    | (_, vpre), (i, v), (_, vpost) when vpre > v && vpost > v -> Some i
    | _ -> None)

这不适用于图表中的数据,因为它过于简单化了,但它应该为您提供一些起点。在实践中,您可能需要添加一些平滑处理(以避免将所有尖峰识别为局部最小值/最大值)。

【讨论】:

  • 感谢您提供这段优雅的代码 :) 我猜您也可以使用类似的窗口化技术来创建先前看到的值的移动均方根值并找到一个最小值/最大值与此有足够的偏差,因此 RMS 值将被重置,您将继续寻找下一个最小值/最大值。
【解决方案2】:

使用 Linq 尝试这样的事情:

YourArray.Where(/*your condition for a "local" portion of the array*/).Min(t => t.Date);
YourArray.Where(/*your condition for a "local" portion of the array*/).Max(t => t.Date);

【讨论】:

  • 使用哪些本地部分...可以是多种多样的。
  • 我不确定您使用什么条件来定义数组的各种“本地部分”,所以很难说。你能详细说明你是如何定义这个的吗?
  • 它可以是多种多样的。该数据来自机器并基于其操作,为了简单起见,可以将其称为“mmachine 的燃料水平”,因此我的数据燃料水平与时间的关系。所以,数据频率取决于它的运行,如果它工作,我每 5 秒有一次数据,如果它不工作,我每天有一次数据。
【解决方案3】:

您必须手动编写此代码,因为要计算局部最小值/最大值,您需要考虑多个参数,例如时间范围、变化率等。您可以使用一些算法来执行此操作,但它没有在 .NET 库中实现。

【讨论】:

  • 不,对我来说还不够,太简单了。如果您在图表上看到我的蓝点,我不想获得整个数据的最大值和最小值。我想得到局部的最小值最大值,所以它也是关于一些趋势分析和数据过滤的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
  • 2011-08-16
  • 2017-12-13
  • 1970-01-01
相关资源
最近更新 更多