我最终得到了大量的数字(从数据库中提取)。
所以,它可能看起来像:[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个平均数。
答案 0 :(得分: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]
答案 1 :(得分: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;
如果您不想在结果中使用块编号,可以将其包装在另一个仅投影chunk_avg
的外部选择中,或从chunk
子句中删除select
字段并在chunk
和row/10
子句中将group by
替换为order by
。
答案 2 :(得分:1)
平均值 NOT 与整体平均值相同。除非你不要求太高的精确度,或者不需要平均子集,否则我不推荐它。