【问题标题】:How to efficently calculate mean and standard deviation for a very large series of numbers?如何有效地计算大量数字的均值和标准差?
【发布时间】:2014-01-30 05:03:42
【问题描述】:

通过 Win 7 上的 Visual Studio 中的 C#,我需要计算大量数字的均值和标准差。这些数字是从文件中读取的。 可能有十万甚至更多的数字。如果我不想将它们保存在数组或列表等数据结构中,因为这可能不是内存效率,如何有效地进行计算。

我还需要将数字打印到文件中。

答案在 How to calculate a standard deviation [array] 帮不了。

任何帮助将不胜感激!

最好的

【问题讨论】:

  • “...的答案无济于事” - 为什么?对于任何可能试图帮助您的人来说,这可能是非常有用的信息。
  • 如果数据的后半部分与前半部分有显着差异,则数据严重偏斜,计算均值/偏差不是有意义的操作。所以只看前半部分就足够了。迭代地应用该规则,直到您的代码足够快:)
  • 在不将数字保留在列表中的情况下计算标准差的经典方法如 this answer 所示。尽管显示的函数使用了一个列表,但它会单独处理每个数字一次,因此它可以很容易地适应从文件中读取数字时的处理,而无需将它们保存在列表中。

标签: c# windows visual-studio math mean


【解决方案1】:

一万个数字不算什么。几百万足以让您考虑记忆,但可能还不足以让您将它们全部放入记忆中。

如果您达到数十亿、数万亿或更多,那么您可能无法将它们拉入内存。看来你还没到那个地步。

您可以将它们全部拉入List,无需担心。

话虽如此,LINQ 的Average 方法实际上并不需要急切地加载所有数字来计算平均值;它可以只使用“当前”项修改聚合值然后丢弃它,因此它的内存占用非常低。您在问题中链接到的所有 StdDev 方法也是如此;它们都有一个小的常量内存占用。

因此,您需要做的就是创建一个IEnumerable<double>,它代表文件中延迟填充的数字序列,您可以在其上调用这些方法。无需急切地将它们加载到内存中。

【讨论】:

  • 能否请您给我看一个 C# 的简单示例?我是 C# 新手。谢谢!
  • @user2420472 您链接到的问题通过示例向您展示了如何做到这一点,并且整个网络上有 大量 的示例;只是做一些搜索。
  • 问题询问如何在不使用数组或列表的情况下有效地计算结果。说保留一万个数字的列表是“没有的”(因为它不会消耗您认为可用的大量资源)并不能回答问题,因为它违反了明确规定的约束(没有数组或列表)和明确的既定目标(效率)。
  • @EricPostpischil 看来您读到一半就停止了阅读,也没有看最后两段。在首先说明没有必要之后,我确实回答了所提出的实际问题。
  • @Servy:我的评论并没有说其余的答案是错误的。它说关于将数据保存在列表中的评论并不能回答这个问题。更具体地说,前三段是不恰当的。
【解决方案2】:

在一次处理一个数字时计算平均值和标准差:

CountSumSumOfSquares 初始化为零。

当您收到每个号码时,将Count 加一,将号码加至Sum,并将号码的平方加至SumOfSquares

处理完每个号码后,将Mean 设置为Sum / Count,并将StandardDeviation 设置为Math.Sqrt(SumOfSquares / Count - Mean * Mean)

后一个公式的推导显示在the Wikipedia page for standard deviation

【讨论】:

    【解决方案3】:

    100 万个数字(32 位 int)大约需要 4mb 的内存,这很小。

    只需将它们全部加载到 int 列表中,然后您就可以使用内置的 linq 方法对它们进行操作。

    更新: 如何使用 linq 进行操作:

    math stats with Linq

    【讨论】:

    • 问题询问如何在不使用数组或列表的情况下有效地计算结果。声明保留一百万个数字的列表仅使用“少量”内存并不能回答问题,因为它违反了明确规定的约束(没有数组或列表)和明确规定的目标(效率)。
    猜你喜欢
    • 1970-01-01
    • 2014-03-21
    • 2021-06-15
    • 2021-10-09
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多