2

我得到了最终相当于大量数字的内容(从数据库中提取)。

所以,它可能看起来像:[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 个平均数。

4

3 回答 3

4
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]
于 2013-03-20T13:42:42.313 回答
4

该切片平均值可以通过数据库选择直接获取。您的数据库引擎几乎可以肯定进行分组和平均计算至少比 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

如果您不希望结果中出现块编号,则可以将其包装在另一个仅包含 projects 的外部 select 中chunk_avg,或者从子句中删除chunk字段并在and子句中select逐字替换chunk为 with 。row/10group byorder by

于 2013-03-20T15:43:39.620 回答
1

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

于 2013-03-20T13:43:32.943 回答