【问题标题】:Average a large array?平均一个大数组?
【发布时间】:2023-03-24 05:14:01
【问题描述】:

我最终得到了一大堆数字(从数据库中提取)。

所以,它可能看起来像:[1,3,1,2,1,3,1,2,3,1,2,3,1,3,1,3,1,1,3,2,3,3,3,3,1,1,1,1,3,2,1]

除了可能是 50,000 个数字而不是几十个。最小的数字永远是1,最大的数字是3

我需要做的是找到某种滚动平均值,这样我就可以在易于管理的折线图中显示数据。

所以也许平均每 5-10 个数据点的数量?只是不确定处理此类事情的最佳方法是什么。

注意:不希望获得单一平均值。我希望将整个数组提炼成更多的平均点。因此,一个包含 1000 个点的数据集可能会被分解为 10 个平均数。

【问题讨论】:

  • 作为旁注,您的示例中的最高值(编辑前)不是 3。)但真正的问题是,您的“平均值”应该有多精确?
  • 您是否有理由不直接从数据库中选择平均值?
  • @mcfinnigan 我不需要单个平均值...我需要多个平均数据点。所以一个包含 1000 个数字的数据集可能有 10 个平均点。
  • @Shpigford 您的数据库可以通过按行号分组来生成切片的平均值。在这方面,DB 几乎肯定会比 ruby​​ 至少快一个数量级。
  • @dbenhur:那么,想用那个解决方案添加答案吗?

标签: ruby arrays postgresql average


【解决方案1】:
1.9.3p327 :001 > a = [1,3,1,2,1,3,1,2,3,1,2,3,1,3,1,3,1,1,3,2,3,3,3,3,1,1,1,1,3,2,1]
 => [1, 3, 1, 2, 1, 3, 1, 2, 3, 1, 2, 3, 1, 3, 1, 3, 1, 1, 3, 2, 3, 3, 3, 3, 1, 1, 1, 1, 3, 2, 1]
1.9.3p327 :002 > a.each_cons(10).map { |subarray| subarray.reduce(0.0, :+) / subarray.size }
 => [1.8, 1.9, 1.9, 1.9, 2.0, 2.0, 2.0, 2.0, 1.9, 1.9, 2.0, 2.1, 2.1, 2.3, 2.3, 2.3, 2.1, 2.1, 2.1, 2.1, 2.1, 1.9]

但这在性能方面并不好。它是 O(NM),其中 N 是数组的大小,M 是窗口的大小(在本例中为 10)。

UPD:或者您可以使用each_slice,如果您需要显着“减少”数组大小:

1.9.3p327 :002 > a.each_slice(10).map { |subarray| subarray.reduce(0.0, :+) / subarray.size }
 => [1.8, 2.0, 2.1, 1.0]

【讨论】:

  • 对于 OP 想要的,“所以也许平均每 5-10 个数据点的数量?”,each_cons 应该替换为 each_slice
  • each_conseach_slice 所做的有什么区别? each_slice 可能是我所追求的……但很好奇 each_cons 到底在做什么。
  • each_slice 获取每个n 元素,而each_cons 向前滑动一个大小为n 的窗口,一次一个元素。 Enumerable Docs
【解决方案2】:

可以通过数据库选择直接获取此切片平均值。您的数据库引擎几乎可以肯定进行分组和平均计算至少比 ruby​​ 快一个数量级,此外,您将通过线路从数据库传输到程序的数据要少得多,并显着减少在您的程序中实例化的对象数量ruby 程序来表示结果集。

所以,如果您的原始查询看起来像这样(在 Postgresql 中):

select value from mytable;

您可以修改它以产生每十个项目的平均值,如下所示:

select avg(value) as chunk_avg, row/10 as chunk
from 
  (select value, row_number() over () - 1 as row
   from mytable) x
group by chunk
order by chunk;

SqlFiddle

如果您不希望结果中出现块编号,则可以将其包装在另一个仅投射 chunk_avg 的外部选择中,或者从 select 子句中删除 chunk 字段并从字面上替换 chunkgroup byorder by 子句中使用row/10

【讨论】:

    【解决方案3】:

    平均值与整体平均值相同。除非您不要求很高的精度,或者不需要平均子集,否则我不推荐它。

    【讨论】:

    • 这并不是真正的“平均数”...它只是在数据范围内将一堆数字分解为几个平均数,而不是单个平均数。
    • 那么你的想法是黄金(在子集中平均)
    猜你喜欢
    • 1970-01-01
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2022-11-12
    • 2018-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多