2011-08-23 12 views
8

Podam pewien kontekst, więc ma to sens. Przechwytywam Oceny Klientów dla Produktów w tabeli (Rating) i chcę mieć możliwość zwrócenia Łącznej średniej ruchomej ocen według czasu.Jak obliczyć łączną średnią ruchomą w Pythonie/SQLAlchemy/Flask

Podstawowym przykładem następująco biorąc rating dziennie:

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... 

Staram się myśleć o podejściu, które nie będą skalowane strasznie.

Mój obecny pomysł ma mieć funkcję, która jest wyzwolony, gdy wiersz jest wstawiany do tabeli rankingu, który działa z cum Śr podstawie poprzedniego rzędu dla tego produktu

Więc pola byłoby coś takiego:

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

Ale wydaje się, że dość sprytny sposób przechowywania danych.

Jaki byłby (lub jakikolwiek) sposób na osiągnięcie tego? Gdybym miał użyć "rodzaju wyzwalania", jak to robisz w SQLAlchemy?

Wszelkie rady zostały docenione!

+1

Z pewnością można to zrobić w SQL - patrz: http://stackoverflow.com/questions/4107479/subqueries-aggregates-and-aggravation/4107784#4107784 ... Nie jestem pewien, jak uzyskać SQLAlchemy generować takie zapytanie (i twoja baza danych może nie obsługiwać niezbędnej składni). –

+0

@Sean Vieria: Dzięki za link - Wiem, że to możliwe w czystym SQL, ale znowu oznacza to, że liczba ocen rośnie, wydajność pogarsza się, gdy obliczenia są wykonywane w każdym rzędzie. Mogę spróbować wprowadzić mój pierwotny pomysł przechowywania go, ponieważ każdy wiersz jest wprowadzany, tak jak wiem, który będzie skalowany. Po prostu nie byłem pewien, czy jest coś podstawowego, co przeoczyłem. Dzięki za pomoc! – mwan

Odpowiedz

5

nie wiem o SQLAlchemy, ale mogę używać podejście tak:

  • Przechowuj skumulowaną średnią i liczbę ocen oddzielnie od poszczególnych ocen.
  • Za każdym razem dostać nowy rating, zaktualizuj skumulowaną średnią i Ilość ocen:
    • NEW_COUNT = old_count + 1
    • new_average = ((old_average * old_count) + new_rating)/NEW_COUNT
  • Opcjonalnie, przechowaj wiersz dla każdej nowej oceny.

Aktualizacja średniej i liczby ocen może zostać wykonana za pomocą pojedynczej instrukcji SQL.

+0

Dzięki, zaimplementowałem większość z nich wczoraj i to jest podejście, które w końcu i tak do mnie dotarło, właśnie muszę dokończyć implementację, a następnie odeślę z powrotem kod, którego użyłem.Skala ta jest odpowiedzialna i przewidywalna, i właśnie tego szukałem. – mwan

+0

A jeśli użytkownik może edytować ocenę? To podejście zadziałałoby? – user2990084

+1

O wiele łatwiej jest przechowywać * sumę * i liczbę, niż * średnią * i liczbę. –

-5

myślę, że należy przechowywać MA w wykazie 2 elementów, byłoby znacznie bardziej prosta:

#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] 

Bye

+0

Sugerujesz, że przechowuję listę po stronie Pythona (tj. Muszę przeliczyć całą listę dla każdego uruchamianego zapytania)? Nie jestem pewien, czy podążam. Czy nie byłoby to tak źle, jak rośnie liczba ocen? – mwan

Powiązane problemy