Private
Public Access
1
0

Merge branch 'release/v5.97'

This commit is contained in:
Sander Roosendaal
2018-02-25 09:21:01 +01:00
5 changed files with 31 additions and 9 deletions
+3 -1
View File
@@ -72,6 +72,7 @@ def time_in_path(df,p,maxmin='max'):
else: else:
b = (~df['inpolygon']).shift(1)+df['inpolygon'] b = (~df['inpolygon']).shift(1)+df['inpolygon']
if len(df[b==2]): if len(df[b==2]):
return df[b==2]['time'].min(),df[b==2]['cum_dist'].min() return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
@@ -247,9 +248,10 @@ def get_time_course(ws,course):
rowdata = dataprep.getsmallrowdata_db( rowdata = dataprep.getsmallrowdata_db(
columns, columns,
ids = [w.id], ids = [w.id],
doclean=True, doclean=False,
workstrokesonly=False workstrokesonly=False
) )
rowdata.rename(columns = { rowdata.rename(columns = {
' latitude':'latitude', ' latitude':'latitude',
' longitude':'longitude', ' longitude':'longitude',
+7 -4
View File
@@ -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:
+5 -1
View File
@@ -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>
+12
View File
@@ -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()
+4 -3
View File
@@ -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(),
@@ -12687,7 +12688,7 @@ def plannedsession_view(request,id=0,rowerid=0,
coursetimeseconds, coursetimeseconds,
coursemeters, coursemeters,
coursecompleted coursecompleted
) = courses.get_time_course(ws,ps.course) ) = courses.get_time_course([w],ps.course)
intsecs = int(coursetimeseconds) intsecs = int(coursetimeseconds)
microsecs = int(1.e6*(coursetimeseconds-intsecs)) microsecs = int(1.e6*(coursetimeseconds-intsecs))