added weighted average - rScore now uses weighted average
This commit is contained in:
@@ -56,7 +56,7 @@ import sys
|
|||||||
|
|
||||||
import utils
|
import utils
|
||||||
import datautils
|
import datautils
|
||||||
from utils import lbstoN,myqueue,is_ranking_piece
|
from utils import lbstoN,myqueue,is_ranking_piece,wavg
|
||||||
|
|
||||||
from timezonefinder import TimezoneFinder
|
from timezonefinder import TimezoneFinder
|
||||||
|
|
||||||
@@ -2234,16 +2234,19 @@ def workout_rscore(w):
|
|||||||
df,row = getrowdata_db(id=w.id)
|
df,row = getrowdata_db(id=w.id)
|
||||||
df = clean_df_stats(df,workstrokesonly=False)
|
df = clean_df_stats(df,workstrokesonly=False)
|
||||||
|
|
||||||
|
df['deltat'] = df['time'].diff()
|
||||||
duration = df['time'].max()-df['time'].min()
|
duration = df['time'].max()-df['time'].min()
|
||||||
duration /= 1.0e3
|
duration /= 1.0e3
|
||||||
pwr4 = df['power']**(4.0)
|
df['pwr4'] = df['power']**(4.0)
|
||||||
normp = (pwr4.mean())**(0.25)
|
pwr4mean = wavg(df,'pwr4','deltat')
|
||||||
|
pwrmean = wavg(df,'power','deltat')
|
||||||
|
normp = (pwr4mean)**(0.25)
|
||||||
if not np.isnan(normp):
|
if not np.isnan(normp):
|
||||||
ftp = float(r.ftp)
|
ftp = float(r.ftp)
|
||||||
if w.workouttype in ('water','coastal'):
|
if w.workouttype in ('water','coastal'):
|
||||||
ftp = ftp*(100.-r.otwslack)/100.
|
ftp = ftp*(100.-r.otwslack)/100.
|
||||||
|
|
||||||
intensityfactor = df['power'].mean()/float(ftp)
|
intensityfactor = pwrmean/float(ftp)
|
||||||
intensityfactor = normp/float(ftp)
|
intensityfactor = normp/float(ftp)
|
||||||
tss = 100.*((duration*normp*intensityfactor)/(3600.*ftp))
|
tss = 100.*((duration*normp*intensityfactor)/(3600.*ftp))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
<h1>Workout Statistics for {{ workout.name }}</h1>
|
<h1>Workout Statistics for {{ workout.name }}</h1>
|
||||||
<p>
|
<p>
|
||||||
This is an experimental page which just lists a bunch of statistics for
|
This is an experimental page which just lists a bunch of statistics for
|
||||||
your workout. This page is under rapid development.
|
your workout. The mean is of a metric is the mean with equal weight for
|
||||||
|
each stroke. The time weighted mean takes into account the stroke
|
||||||
|
duration.
|
||||||
</p>
|
</p>
|
||||||
<div class="grid_2 alpha">
|
<div class="grid_2 alpha">
|
||||||
<p>
|
<p>
|
||||||
@@ -55,6 +57,8 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Mean</td><td>{{ value.mean|floatformat:-2 }}</td>
|
<td>Mean</td><td>{{ value.mean|floatformat:-2 }}</td>
|
||||||
|
</tr><tr>
|
||||||
|
<td>Time Weighted Mean</td><td> {{ value.wmean|floatformat:-2 }}</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td>Minimum</td><td>{{ value.min|floatformat:-2 }}</td>
|
<td>Minimum</td><td>{{ value.min|floatformat:-2 }}</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
|
|||||||
@@ -319,3 +319,15 @@ def my_dict_from_instance(instance,model):
|
|||||||
thedict[fname] = (verbosename,value)
|
thedict[fname] = (verbosename,value)
|
||||||
|
|
||||||
return thedict
|
return thedict
|
||||||
|
|
||||||
|
def wavg(group, avg_name, weight_name):
|
||||||
|
""" http://stackoverflow.com/questions/10951341/pandas-dataframe-aggregate-function-using-multiple-columns
|
||||||
|
In rare instance, we may not have weights, so just return the mean. Customize this if your business case
|
||||||
|
should return otherwise.
|
||||||
|
"""
|
||||||
|
d = group[avg_name]
|
||||||
|
w = group[weight_name]
|
||||||
|
try:
|
||||||
|
return (d * w).sum() / w.sum()
|
||||||
|
except ZeroDivisionError:
|
||||||
|
return d.mean()
|
||||||
|
|||||||
@@ -754,7 +754,7 @@ from utils import (
|
|||||||
geo_distance,serialize_list,deserialize_list,uniqify,
|
geo_distance,serialize_list,deserialize_list,uniqify,
|
||||||
str2bool,range_to_color_hex,absolute,myqueue,get_call,
|
str2bool,range_to_color_hex,absolute,myqueue,get_call,
|
||||||
calculate_age,rankingdistances,rankingdurations,
|
calculate_age,rankingdistances,rankingdurations,
|
||||||
is_ranking_piece,my_dict_from_instance
|
is_ranking_piece,my_dict_from_instance,wavg
|
||||||
)
|
)
|
||||||
|
|
||||||
import datautils
|
import datautils
|
||||||
@@ -7446,7 +7446,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
|
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
|
||||||
|
datadf['deltat'] = datadf['time'].diff()
|
||||||
|
|
||||||
if datadf.empty:
|
if datadf.empty:
|
||||||
datadf,row = dataprep.getrowdata_db(id=id)
|
datadf,row = dataprep.getrowdata_db(id=id)
|
||||||
@@ -7472,6 +7472,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
|||||||
for field,verbosename in fielddict.iteritems():
|
for field,verbosename in fielddict.iteritems():
|
||||||
thedict = {
|
thedict = {
|
||||||
'mean':datadf[field].mean(),
|
'mean':datadf[field].mean(),
|
||||||
|
'wmean': wavg(datadf, field, 'deltat'),
|
||||||
'min': datadf[field].min(),
|
'min': datadf[field].min(),
|
||||||
'std': datadf[field].std(),
|
'std': datadf[field].std(),
|
||||||
'max': datadf[field].max(),
|
'max': datadf[field].max(),
|
||||||
|
|||||||
Reference in New Issue
Block a user