我有一个大约400万行的快速增长的数据集,以便定义和排除异常值(用于统计/分析用法)我需要算法来考虑此数据集中的所有条目。然而,这是太多的数据加载到内存和我的系统窒息。我目前正在使用它来收集和处理数据:
@scoreInnerFences = innerFence Post.where( :source => 1 ).
order( :score ).
pluck( :score )
使用典型的分治方法是行不通的,我不认为因为每个条目都必须考虑让我的异常计算准确。如何有效地实现这一目标?
innerFence
标识数据集的下四分位数和上四分位数,然后使用这些结果来计算异常值。这是(尚未重构,非DRY)代码:
def q1(s)
q = s.length / 4
if s.length % 2 == 0
return ( s[ q ] + s[ q - 1 ] ) / 2
else
return s[ q ]
end
end
def q2(s)
q = s.length / 4
if s.length % 2 == 0
return ( s[ q * 3 ] + s[ (q * 3) - 1 ] ) / 2
else
return s[ q * 3 ]
end
end
def innerFence(s)
q1 = q1(s)
q2 = q2(s)
iq = (q2 - q1) * 3
if1 = q1 - iq
if2 = q2 + iq
return [if1, if2]
end
答案 0 :(得分:1)
这不是最好的方法,但这是一种简单的方法:
做几个查询。首先计算分数:
q = Post.where(:source => 1).count
然后你做你的计算 然后你取得分数
q1 = Post.where(:source => 1)。 reverse_order(:得分)。 选择(“平均(得分)为分数”)。 偏移量(Q).limit((Q%2)+1)
q2 = Post.where(:source => 1)。 reverse_order(:得分)。 选择(“平均(得分)为分数”)。 偏移量(Q * 3).limit((Q%2)+1)
代码可能不对,但我相信你明白了。
答案 1 :(得分:0)
对于大型数据集,我有时会下载到ActiveRecord下面。这是一个记忆力,即使我想象,使用采摘。当然它的便携性较差,但有时值得。
得分= Post.connection.execute('从得分>按分数排序1的帖子中选择得分')。map(&:first)
不知道这对400万的记录是否有足够的帮助。如果没有,也许看一下存储过程?