Series temporales de sensores

Ingesta de registros diarios por sujeto, agregación temporal, cálculo de métricas derivadas, y comparación pre/post con test pareado o modelos mixtos longitudinales.

Descargar informe PDF

Dataset cargado

940 registros diarios de 33 sujetos, período 2016-04-12 → 2016-05-12. Fuente ejemplo: Fitbit Fitness Tracker Data (público, Kaggle). Los pipelines aceptan cualquier CSV con estructura equivalente (registro diario por sujeto + variables numéricas).

Método aplicado — agregación y métricas

Pipeline

  1. Carga CSV, parseo de fecha (pd.to_datetime).
  2. Cálculo de variables derivadas por registro (ej: MVPA = VeryActive + FairlyActive).
  3. Agregación por sujeto: media / std / N días con datos.
  4. Cálculo de métricas de grupo + porcentaje que cumple umbral (recomendación OMS ≥ 150 min MVPA/sem).

Herramientas

  • pandas — pivot, groupby, resample.
  • numpy — cálculos vectorizados.
  • matplotlib — series temporales + boxplot.
Ver código del pipeline
df["ActivityDate"] = pd.to_datetime(df["ActivityDate"], format="%m/%d/%Y")
df["MVPAminutes"] = df["VeryActiveMinutes"] + df["FairlyActiveMinutes"]

summary = df.groupby("Id").agg(
    n_dias=("ActivityDate", "count"),
    pasos_medios=("TotalSteps", "mean"),
    MVPA_min_media=("MVPAminutes", "mean"),
    sedentario_min_media=("SedentaryMinutes", "mean"),
    calorias_medias=("Calories", "mean"),
).reset_index()

# Cumplimiento umbral OMS
pct_activos_OMS = (summary["MVPA_min_media"] >= 150 / 7).mean() * 100

Resultado — métricas de grupo

7519
Pasos medios / día
±3576
33.6
MVPA min/día
±29.9
999
Sedentario min/día
±228
57.6%
Cumplen OMS
≥150 min MVPA/sem

Serie temporal de pasos diarios (grupo)

Steps

Distribución entre sujetos

Boxplot

Método aplicado — análisis pre / post

Diseño

División temporal del período en dos mitades. Por cada sujeto se calcula la media pre y la media post, generando pares. Se aplica test-t pareado sobre las diferencias intra-sujeto (grados de libertad = n − 1).

Extensiones soportadas

  • Modelos mixtos con statsmodels.MixedLM (intercepto + pendiente aleatorios por sujeto).
  • Propensity score matching contra control histórico (sklearn).
  • Bootstrap del efecto (n=1000) para IC no-paramétrico.
Ver código del pipeline pre/post
midpoint = df["ActivityDate"].min() + (df["ActivityDate"].max() - df["ActivityDate"].min()) / 2
df["fase"] = np.where(df["ActivityDate"] < midpoint, "pre", "post")

piv = df.groupby(["Id", "fase"]).agg(
    MVPA=("MVPAminutes", "mean"),
    pasos=("TotalSteps", "mean"),
).unstack("fase")
piv.columns = [f"{a}_{b}" for a, b in piv.columns]
piv = piv.dropna()
piv["delta_MVPA"] = piv["MVPA_post"] - piv["MVPA_pre"]

# Test t pareado (simplificado)
mean_d = piv["delta_MVPA"].mean()
sd_d = piv["delta_MVPA"].std(ddof=1)
t_stat = mean_d / (sd_d / np.sqrt(len(piv)))

Resultado — pre / post

32
n pareados
-4.8
ΔMVPA min/día
SD 16.4
-581
ΔPasos/día
-1.64
t simulado
Pre/post

Resumen completo por sujeto — navegable

Total: 33 sujetos.

IDDíasPasos medios MVPA mediaSedentarioCalorías