如何计算Python/SQLAlchemy/Flask中的累积移动平均数

问题描述:

我将给出一些上下文,这是有道理的。我在表格中收集产品的客户评级(评级),并希望能够根据时间返回评级的累计移动平均值。如何计算Python/SQLAlchemy/Flask中的累积移动平均数

一个基本的例子如下每天服用评级:

02 FEB - Rating: 5 - Cum Avg: 5 
03 FEB - Rating: 4 - Cum Avg: (5+4)/2 = 4.5 
04 FEB - Rating: 1 - Cum Avg: (5+4+1)/3 = 3.3 
05 FEB - Rating: 5 - Cum Avg: (5+4+1+5)/4 = 3.75 
Etc... 

我试图想,不会可怕的缩放方法。

我现在的想法是有一个功能,当行被插入到基于先前行该产品

所以领域会像上工作了射精平均的评分表跳闸:

TABLE: Rating 
| RatingId | DateTime | ProdId | RatingVal | RatingCnt | CumAvg | 

但是,这似乎是一个相当狡猾的方式来存储数据。

什么是(或任何)方式来实现这一目标?如果我要使用各种“触发器”,那么你如何在SQLAlchemy中做到这一点?

任何和所有的建议表示赞赏!

+1

这绝对有可能在SQL中执行此操作 - 请参阅:http://*.com/questions/4107479/subqueries-aggregates-and-aggravation/4107784#4107784 ...我不确定如何获取SQLAlchemy生成一个这样的查询(并且您的数据库可能不支持必要的语法)。 –

+0

@Sean Vieria:感谢您的链接 - 我知道它可能在纯SQL中,但这又意味着随着评级数量的增长,性能随着每行的计算变得更糟。我可能会尝试实现我原来的想法,即在输入每行时存储它,因为我知道这将会缩放。我只是不确定是否有某种基本的东西可以忽略。谢谢您的帮助! – mwan

我不知道SQLAlchemy的,但我可能会使用的方法像这样:

  • 将累计平均值和评分数与个人评分分开存储。
  • 每次你得到一个新的等级,更新累计平均与评级计数:
    • NEW_COUNT = old_count + 1
    • new_average =((old_average * old_count)+ new_rating)/ NEW_COUNT
  • 可选地,为每个新评级存储一行。

更新平均值和评估计数可以使用单个SQL语句完成。

+0

谢谢,我昨天实现了它的大部分,这是我最终采取的方法,我刚刚完成实现它,然后我会回发我使用的代码。它负责任地和可预测地扩展,这正是我所追求的。 – mwan

+0

如果用户可以编辑评分?这种方法可行吗? – user2990084

+1

存储* sum *和count,而不是* average *和count更容易。 –

我想你应该存储在2元列表中的MA,它会更简单:

#first rating 5 is rating number 0 
a = [5,0] 

#next: 
for i in rating: 
a = [(a[0]*a[1]+lastRating)/(a[1]+1),a[1]+1] 

再见

+0

你是否建议我存储Python列表(即必须重新计算每个查询运行的整个列表)?我不确定我是否遵守。这会不会随着收视率的增长而严重恶化? – mwan