Skip to content

Commit 8a3f3fb

Browse files
committed
feat: add new StepsTop1 and StepsTop30 metrics
1 parent fadc6ad commit 8a3f3fb

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

src/stepcount/stepcount.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ def main():
197197
info['StepsDayMed_Weekday'] = steps_summary['weekday_med_steps']
198198
info['StepsDayMin_Weekday'] = steps_summary['weekday_min_steps']
199199
info['StepsDayMax_Weekday'] = steps_summary['weekday_max_steps']
200+
# steps top 1
201+
info['StepsTop1(steps/min)'] = steps_summary['med_top1']
202+
info['StepsTop1(steps/min)_Weekend'] = steps_summary['weekend_med_top1']
203+
info['StepsTop1(steps/min)_Weekday'] = steps_summary['weekday_med_top1']
204+
# steps top 30
205+
info['StepsTop30(steps/min)'] = steps_summary['med_top30']
206+
info['StepsTop30(steps/min)_Weekend'] = steps_summary['weekend_med_top30']
207+
info['StepsTop30(steps/min)_Weekday'] = steps_summary['weekday_med_top30']
200208
# walking, overall stats
201209
info['TotalWalking(mins)'] = steps_summary['total_walk']
202210
info['WalkingDayAvg(mins)'] = steps_summary['avg_walk']
@@ -249,6 +257,14 @@ def main():
249257
info['StepsDayMedAdjusted_Weekday'] = steps_summary_adj['weekday_med_steps']
250258
info['StepsDayMinAdjusted_Weekday'] = steps_summary_adj['weekday_min_steps']
251259
info['StepsDayMaxAdjusted_Weekday'] = steps_summary_adj['weekday_max_steps']
260+
# steps top 1
261+
info['StepsTop1Adjusted(steps/min)'] = steps_summary_adj['med_top1']
262+
info['StepsTop1Adjusted(steps/min)_Weekend'] = steps_summary_adj['weekend_med_top1']
263+
info['StepsTop1Adjusted(steps/min)_Weekday'] = steps_summary_adj['weekday_med_top1']
264+
# steps top 30
265+
info['StepsTop30Adjusted(steps/min)'] = steps_summary_adj['med_top30']
266+
info['StepsTop30Adjusted(steps/min)_Weekend'] = steps_summary_adj['weekend_med_top30']
267+
info['StepsTop30Adjusted(steps/min)_Weekday'] = steps_summary_adj['weekday_med_top30']
252268
# walking, overall stats
253269
info['TotalWalkingAdjusted(mins)'] = steps_summary_adj['total_walk']
254270
info['WalkingDayAvgAdjusted(mins)'] = steps_summary_adj['avg_walk']
@@ -618,6 +634,11 @@ def _median(x, min_wear=None, dt=None):
618634
return np.nan
619635
return x.median()
620636

637+
def _nlargest(x, min_wear=None, n=1):
638+
if not _is_enough(x, min_wear, dt):
639+
return np.nan
640+
return x.nlargest(n).mean()
641+
621642
def _percentile_at(x, ps=(5, 25, 50, 75, 95), min_wear=None, dt=None):
622643
percentiles = {f'p{p:02}_at': np.nan for p in ps}
623644
if not _is_enough(x, min_wear, dt):
@@ -669,6 +690,19 @@ def _tdelta_to_str(tdelta):
669690
weekday_med_steps = day_of_week[day_of_week.index < 5].median()
670691
weekday_min_steps = day_of_week[day_of_week.index < 5].min()
671692
weekday_max_steps = day_of_week[day_of_week.index < 5].max()
693+
694+
daily_top1 = minutely_steps.resample('D').agg(_nlargest, min_wear=1, n=1).rename('StepsTop1(steps/min)')
695+
top1_7d = utils.impute_days(daily_top1).groupby(daily_top1.index.weekday).mean()
696+
med_top1 = top1_7d.median()
697+
weekend_med_top1 = top1_7d[top1_7d.index >= 5].median()
698+
weekday_med_top1 = top1_7d[top1_7d.index < 5].median()
699+
700+
daily_top30 = minutely_steps.resample('D').agg(_nlargest, min_wear=30, n=30).rename('StepsTop30(steps/min)')
701+
top30_7d = utils.impute_days(daily_top30).groupby(daily_top30.index.weekday).mean()
702+
med_top30 = top30_7d.median()
703+
weekend_med_top30 = top30_7d[top30_7d.index >= 5].median()
704+
weekday_med_top30 = top30_7d[top30_7d.index < 5].median()
705+
672706
else:
673707
# crude (unadjusted) estimates ignore NAs
674708
minutely_steps = Y.resample('T').agg(_sum).rename('Steps')
@@ -689,6 +723,16 @@ def _tdelta_to_str(tdelta):
689723
weekday_min_steps = daily_steps[daily_steps.index.weekday < 5].min()
690724
weekday_max_steps = daily_steps[daily_steps.index.weekday < 5].max()
691725

726+
daily_top1 = minutely_steps.resample('D').agg(_nlargest, min_wear=1, n=1).rename('StepsTop1(steps/min)')
727+
med_top1 = daily_top1.median()
728+
weekend_med_top1 = daily_top1[daily_top1.index.weekday >= 5].median()
729+
weekday_med_top1 = daily_top1[daily_top1.index.weekday < 5].median()
730+
731+
daily_top30 = minutely_steps.resample('D').agg(_nlargest, min_wear=30, n=30).rename('StepsTop30(steps/min)')
732+
med_top30 = daily_top30.median()
733+
weekend_med_top30 = daily_top30[daily_top30.index.weekday >= 5].median()
734+
weekday_med_top30 = daily_top30[daily_top30.index.weekday < 5].median()
735+
692736
total_steps = daily_steps.sum() if not daily_steps.isna().all() else np.nan # note that .sum() returns 0 if all-NaN
693737
# weekend/weekday totals
694738
weekend_total_steps = daily_steps[daily_steps.index.weekday >= 5].pipe(lambda x: x.sum() if not x.isna().all() else np.nan)
@@ -763,6 +807,8 @@ def _tdelta_to_str(tdelta):
763807
daily_steps = pd.concat([
764808
daily_walk,
765809
daily_steps.round().astype(pd.Int64Dtype()),
810+
daily_top1,
811+
daily_top30,
766812
# convert timedelta to human-friendly format
767813
daily_ptile_at.rename(columns={
768814
'p05_at': 'Steps5thAt',
@@ -791,6 +837,12 @@ def _tdelta_to_str(tdelta):
791837
weekday_med_steps = utils.nanint(np.round(weekday_med_steps))
792838
weekday_min_steps = utils.nanint(np.round(weekday_min_steps))
793839
weekday_max_steps = utils.nanint(np.round(weekday_max_steps))
840+
med_top1 = utils.nanint(np.round(med_top1))
841+
weekend_med_top1 = utils.nanint(np.round(weekend_med_top1))
842+
weekday_med_top1 = utils.nanint(np.round(weekday_med_top1))
843+
med_top30 = utils.nanint(np.round(med_top30))
844+
weekend_med_top30 = utils.nanint(np.round(weekend_med_top30))
845+
weekday_med_top30 = utils.nanint(np.round(weekday_med_top30))
794846
hour_steps = hour_steps.round().astype(pd.Int64Dtype())
795847
weekend_hour_steps = weekend_hour_steps.round().astype(pd.Int64Dtype())
796848
weekday_hour_steps = weekday_hour_steps.round().astype(pd.Int64Dtype())
@@ -819,6 +871,14 @@ def _tdelta_to_str(tdelta):
819871
'weekday_med_steps': weekday_med_steps,
820872
'weekday_min_steps': weekday_min_steps,
821873
'weekday_max_steps': weekday_max_steps,
874+
# steps top 1
875+
'med_top1': med_top1,
876+
'weekend_med_top1': weekend_med_top1,
877+
'weekday_med_top1': weekday_med_top1,
878+
# steps top 30
879+
'med_top30': med_top30,
880+
'weekend_med_top30': weekend_med_top30,
881+
'weekday_med_top30': weekday_med_top30,
822882
# walking, overall stats
823883
'total_walk': total_walk,
824884
'avg_walk': avg_walk,

0 commit comments

Comments
 (0)