2011-08-23 148 views
8

我將給出一些上下文,這是有道理的。我在表格中收集產品的客戶評級(評級),並希望能夠根據時間返回評級的累計移動平均值。如何計算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://stackoverflow.com/questions/4107479/subqueries-aggregates-and-aggravation/4107784#4107784 ...我不確定如何獲取SQLAlchemy生成一個這樣的查詢(並且您的數據庫可能不支持必要的語法)。 –

+0

@Sean Vieria:感謝您的鏈接 - 我知道它可能在純SQL中,但這又意味着隨着評級數量的增長,性能隨着每行的計算變得更糟。我可能會嘗試實現我原來的想法,即在輸入每行時存儲它,因爲我知道這將會縮放。我只是不確定是否有某種基本的東西可以忽略。謝謝您的幫助! – mwan

回答

5

我不知道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更容易。 –

-5

我想你應該存儲在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