要根据公司的市场容量计算加权平均值,我有一个这样的方法:
class Company < ActiveRecord::Base
def self.weighted_average(column)
market_cap_sum = sum(:market_cap)
array = []
find_each do |company|
next if company.send(column).nil?
next if company.market_cap.nil?
array << (company.market_cap.to_d/market_cap_sum) * company.send(column)
end
array.sum
end
end
此代码工作正常,但计算速度很慢。如果有一种方法可以通过postgresql函数计算,我想用它。
要计算标准差,有这样的函数,但我无法找到如何用加权平均值计算标准差。
Company.select('stddev_pop(price) as stddev')
有可能做我想做的事吗?
答案 0 :(得分:3)
这种方法的数学似乎并不为人所知。享受这个老程序员的伎俩。
CREATE TABLE data (
w real, /* Weight. May be an integer count or other weight. */
v real); /* Value. The value v is to be weighted by w. */
使用值“1”的一个副本和值“10”的十个副本填充表:
insert into data values(1, 1);
insert into data values(10, 2);
然后运行以下查询以获取加权统计值:
SELECT
min(v),
sum(w*v)/sum(w) AS wavg,
max(v),
sqrt((sum(w*v^2)-(sum(w*v)^2)/sum(w))/(sum(w)-1)) AS wstdev
FROM data;
结果是:
min | wavg | max | wstdev
-----+---------+-----+-------------------
1 | 1.90909 | 2 | 0.301511344577763
(1 row)