Skip to content

Commit

Permalink
feat: add new StepsTop1 and StepsTop30 metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
chanshing committed Dec 20, 2024
1 parent fadc6ad commit 3f1bf4e
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/stepcount/stepcount.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ def main():
info['StepsDayMed_Weekday'] = steps_summary['weekday_med_steps']
info['StepsDayMin_Weekday'] = steps_summary['weekday_min_steps']
info['StepsDayMax_Weekday'] = steps_summary['weekday_max_steps']
# steps top 1
info['StepsTop1(steps/min)'] = steps_summary['med_top1']
info['StepsTop1(steps/min)_Weekend'] = steps_summary['weekend_med_top1']
info['StepsTop1(steps/min)_Weekday'] = steps_summary['weekday_med_top1']
# steps top 30
info['StepsTop30(steps/min)'] = steps_summary['med_top30']
info['StepsTop30(steps/min)_Weekend'] = steps_summary['weekend_med_top30']
info['StepsTop30(steps/min)_Weekday'] = steps_summary['weekday_med_top30']
# walking, overall stats
info['TotalWalking(mins)'] = steps_summary['total_walk']
info['WalkingDayAvg(mins)'] = steps_summary['avg_walk']
Expand Down Expand Up @@ -249,6 +257,14 @@ def main():
info['StepsDayMedAdjusted_Weekday'] = steps_summary_adj['weekday_med_steps']
info['StepsDayMinAdjusted_Weekday'] = steps_summary_adj['weekday_min_steps']
info['StepsDayMaxAdjusted_Weekday'] = steps_summary_adj['weekday_max_steps']
# steps top 1
info['StepsTop1Adjusted(steps/min)'] = steps_summary_adj['med_top1']
info['StepsTop1Adjusted(steps/min)_Weekend'] = steps_summary_adj['weekend_med_top1']
info['StepsTop1Adjusted(steps/min)_Weekday'] = steps_summary_adj['weekday_med_top1']
# steps top 30
info['StepsTop30Adjusted(steps/min)'] = steps_summary_adj['med_top30']
info['StepsTop30Adjusted(steps/min)_Weekend'] = steps_summary_adj['weekend_med_top30']
info['StepsTop30Adjusted(steps/min)_Weekday'] = steps_summary_adj['weekday_med_top30']
# walking, overall stats
info['TotalWalkingAdjusted(mins)'] = steps_summary_adj['total_walk']
info['WalkingDayAvgAdjusted(mins)'] = steps_summary_adj['avg_walk']
Expand Down Expand Up @@ -618,6 +634,11 @@ def _median(x, min_wear=None, dt=None):
return np.nan
return x.median()

def _nlargest(x, min_wear=None, n=1):
if not _is_enough(x, min_wear, dt):
return np.nan
return x.nlargest(n).mean()

def _percentile_at(x, ps=(5, 25, 50, 75, 95), min_wear=None, dt=None):
percentiles = {f'p{p:02}_at': np.nan for p in ps}
if not _is_enough(x, min_wear, dt):
Expand Down Expand Up @@ -669,6 +690,17 @@ def _tdelta_to_str(tdelta):
weekday_med_steps = day_of_week[day_of_week.index < 5].median()
weekday_min_steps = day_of_week[day_of_week.index < 5].min()
weekday_max_steps = day_of_week[day_of_week.index < 5].max()

daily_top1 = minutely_steps.resample('D').agg(_nlargest, min_wear=1, n=1).rename('StepsTop1(steps/min)')
med_top1 = daily_top1.median()
weekend_med_top1 = daily_top1[daily_top1.index.weekday >= 5].median()
weekday_med_top1 = daily_top1[daily_top1.index.weekday < 5].median()

daily_top30 = minutely_steps.resample('D').agg(_nlargest, min_wear=30, n=30).rename('StepsTop30(steps/min)')
med_top30 = daily_top30.median()
weekend_med_top30 = daily_top30[daily_top30.index.weekday >= 5].median()
weekday_med_top30 = daily_top30[daily_top30.index.weekday < 5].median()

else:
# crude (unadjusted) estimates ignore NAs
minutely_steps = Y.resample('T').agg(_sum).rename('Steps')
Expand All @@ -689,6 +721,16 @@ def _tdelta_to_str(tdelta):
weekday_min_steps = daily_steps[daily_steps.index.weekday < 5].min()
weekday_max_steps = daily_steps[daily_steps.index.weekday < 5].max()

daily_top1 = minutely_steps.resample('D').agg(_nlargest, min_wear=1, n=1).rename('StepsTop1(steps/min)')
med_top1 = daily_top1.median()
weekend_med_top1 = daily_top1[daily_top1.index.weekday >= 5].median()
weekday_med_top1 = daily_top1[daily_top1.index.weekday < 5].median()

daily_top30 = minutely_steps.resample('D').agg(_nlargest, min_wear=30, n=30).rename('StepsTop30(steps/min)')
med_top30 = daily_top30.median()
weekend_med_top30 = daily_top30[daily_top30.index.weekday >= 5].median()
weekday_med_top30 = daily_top30[daily_top30.index.weekday < 5].median()

total_steps = daily_steps.sum() if not daily_steps.isna().all() else np.nan # note that .sum() returns 0 if all-NaN
# weekend/weekday totals
weekend_total_steps = daily_steps[daily_steps.index.weekday >= 5].pipe(lambda x: x.sum() if not x.isna().all() else np.nan)
Expand Down Expand Up @@ -763,6 +805,8 @@ def _tdelta_to_str(tdelta):
daily_steps = pd.concat([
daily_walk,
daily_steps.round().astype(pd.Int64Dtype()),
daily_top1,
daily_top30,
# convert timedelta to human-friendly format
daily_ptile_at.rename(columns={
'p05_at': 'Steps5thAt',
Expand Down Expand Up @@ -791,6 +835,12 @@ def _tdelta_to_str(tdelta):
weekday_med_steps = utils.nanint(np.round(weekday_med_steps))
weekday_min_steps = utils.nanint(np.round(weekday_min_steps))
weekday_max_steps = utils.nanint(np.round(weekday_max_steps))
med_top1 = utils.nanint(np.round(med_top1))
weekend_med_top1 = utils.nanint(np.round(weekend_med_top1))
weekday_med_top1 = utils.nanint(np.round(weekday_med_top1))
med_top30 = utils.nanint(np.round(med_top30))
weekend_med_top30 = utils.nanint(np.round(weekend_med_top30))
weekday_med_top30 = utils.nanint(np.round(weekday_med_top30))
hour_steps = hour_steps.round().astype(pd.Int64Dtype())
weekend_hour_steps = weekend_hour_steps.round().astype(pd.Int64Dtype())
weekday_hour_steps = weekday_hour_steps.round().astype(pd.Int64Dtype())
Expand Down Expand Up @@ -819,6 +869,14 @@ def _tdelta_to_str(tdelta):
'weekday_med_steps': weekday_med_steps,
'weekday_min_steps': weekday_min_steps,
'weekday_max_steps': weekday_max_steps,
# steps top 1
'med_top1': med_top1,
'weekend_med_top1': weekend_med_top1,
'weekday_med_top1': weekday_med_top1,
# steps top 30
'med_top30': med_top30,
'weekend_med_top30': weekend_med_top30,
'weekday_med_top30': weekday_med_top30,
# walking, overall stats
'total_walk': total_walk,
'avg_walk': avg_walk,
Expand Down

0 comments on commit 3f1bf4e

Please sign in to comment.