Skip to main content

Analyze the relationship between menstrual cycle phases and sleep quality using Apple Health data

Project description

redmoon

Herramienta de analisis que cruza datos del ciclo menstrual con metricas de sueno, HRV y frecuencia cardiaca a partir de tu exportacion de Apple Health.

Una sola linea y obtienes un informe con tests estadisticos, correlaciones y deteccion de patrones hormonales en tu sueno.

pip install redmoon
redmoon analyze exportacion.xml

Que encuentra redmoon

Resultados reales con ~6 anos de datos de Apple Health (76 ciclos, 1,153 noches):

Metrica Cambia con el ciclo? Detalle
Temperatura de muneca Si (p < 0.000001) +0.375 C en fase lutea vs folicular
HRV Si (p < 0.000001) -3ms en fase lutea
Frecuencia cardiaca en reposo Si (p < 0.000001) +2bpm en fase lutea
Despertares premenstruales Si (p = 0.034) +1.1 despertares/noche los ultimos 5 dias
Duracion del sueno No (p = 0.28) Sin diferencia entre fases
% REM / % Deep No (p > 0.7) Sin diferencia entre fases
Eficiencia del sueno No (p = 0.21) Sin diferencia entre fases

Conclusion: las hormonas cambian tu fisiologia nocturna de forma muy clara (temperatura, HRV, frecuencia cardiaca), pero el sueno en si solo se ve afectado justo antes del periodo, con mas despertares.


Como usar redmoon con tus datos

1. Exportar datos de Apple Health

En tu iPhone: Salud → foto de perfil → Exportar datos de salud → te genera un zip con exportacion.xml.

2. Instalar

pip install redmoon

Con extras opcionales:

pip install redmoon[all]    # incluye visualizaciones, ML y dashboard
pip install redmoon[viz]    # solo matplotlib + seaborn
pip install redmoon[ml]     # solo scikit-learn

3. Ejecutar analisis

Desde terminal:

# Analisis completo con report en consola
redmoon analyze exportacion.xml

# Guardar report a archivo + CSVs intermedios
redmoon analyze exportacion.xml --output report.txt --csv-dir data/

Como libreria Python:

from redmoon import parse_export, CycleSleepAnalyzer

data = parse_export("exportacion.xml")
analyzer = CycleSleepAnalyzer(data)
report = analyzer.run()

# Report completo en texto
print(report.summary())

# Medias por fase como DataFrame
report.phase_means()

# Tests estadisticos
report.statistical_tests()

# Efecto premenstrual
report.premenstrual_effect()

4. Dashboard interactivo (opcional)

pip install redmoon[all]
streamlit run dashboard.py

5 vistas: resumen, sueno por fase, biomarcadores, efecto premenstrual, tendencia temporal.

5. Notebook de analisis (opcional)

jupyter notebook notebooks/analysis.ipynb

16 secciones con visualizaciones completas, tests estadisticos, prediccion ML, y correlaciones.


Que datos necesitas

redmoon extrae automaticamente del XML de Apple Health:

Dato Fuente Registros tipicos
Fases de sueno (Core, REM, Deep, Awake) Apple Watch Miles
Flujo menstrual App Salud / tracker Cientos
Temperatura de muneca nocturna Apple Watch Ultra / Series 8+ Cientos
HRV (SDNN) Apple Watch Miles
Frecuencia cardiaca en reposo Apple Watch Miles
Perturbaciones respiratorias Apple Watch Cientos

No necesitas todos. El minimo es sueno + periodo. Los biomarcadores (temperatura, HRV, HR) enriquecen el analisis pero son opcionales.


Metodologia

Agregacion nocturna

Cada noche se asigna a la fecha en que empieza el sueno. Si te duermes a las 2:00, esa noche cuenta como el dia anterior. Se filtran noches con <2h de sueno o >16h en cama.

Deteccion de ciclos

Los dias de sangrado consecutivos se agrupan en periodos. Un nuevo periodo empieza cuando hay >5 dias sin sangrado. Ciclos de <21 o >45 dias se excluyen.

Asignacion de fases

Cada ciclo se divide en 4 fases proporcionalmente a su duracion real:

Fase Dias tipicos Que pasa hormonalmente
Menstrual 1-5 Estrogeno y progesterona en minimo. Sangrado. Fatiga.
Folicular 6-13 Estrogeno sube. Mas energia y claridad mental.
Ovulatoria 14-16 Pico de estrogeno y LH. Liberacion del ovulo. Temperatura empieza a subir.
Lutea 17-28+ Progesterona alta. Temperatura +0.3-0.5 C. Al final, caida hormonal → PMS.

La fase lutea se subdivide en lutea temprana y premenstrual (ultimos 5 dias) para aislar el efecto PMS.

Tests estadisticos

  • Kruskal-Wallis: test no parametrico para comparar las 4 fases
  • Mann-Whitney U con correccion de Bonferroni: comparaciones post-hoc por pares
  • Spearman: correlaciones entre metricas
  • Random Forest: prediccion de fase lutea vs no-lutea (F1 = 0.79 con temperatura + HRV + HR)

Limpieza de outliers

  • Eficiencia > 100%: Apple Health puede registrar InBed desde el iPhone y las fases desde el Watch, causando inconsistencias. Se usa max(InBed, sleep+awake) como denominador y se capea al 100%.
  • Ciclos anormales: <21 o >45 dias se excluyen.
  • Noches pre-2020: solo tienen InBed sin desglose en fases (el Watch no lo soportaba).

Estructura del proyecto

redmoon/
├── redmoon/               # Paquete Python (PyPI)
│   ├── __init__.py        #   Exports: parse_export, CycleSleepAnalyzer
│   ├── parser.py          #   XML → DataFrames
│   ├── analyzer.py        #   Analisis + report
│   ├── constants.py       #   Constantes, umbrales y logica de fases
│   └── cli.py             #   CLI: redmoon analyze
├── tests/                 # Tests (pytest, 37 tests)
│   ├── test_parser.py     #   Parser: tipos, columnas, validacion
│   ├── test_analyzer.py   #   Analyzer: pipeline, report, edge cases
│   └── test_constants.py  #   Asignacion de fases y constantes
├── sample_data/           # Datos sinteticos para probar sin Apple Health
├── notebooks/
│   └── analysis.ipynb     # Analisis completo con graficas
├── dashboard.py           # Dashboard Streamlit
├── .github/workflows/     # CI: tests en Python 3.9-3.12
├── data/                  # (gitignored) tus datos privados
├── pyproject.toml
└── LICENSE                # MIT

Desarrollo local

git clone https://github.com/aroaxinping/redmoon.git
cd redmoon
pip install -e ".[all]"
pip install pytest

# Tests
pytest tests/ -v

# Probar con datos de ejemplo (sin necesitar Apple Health)
python -c "
import pandas as pd
from redmoon import CycleSleepAnalyzer
data = {k: pd.read_csv(f'sample_data/{k}.csv', parse_dates=['start','end'] if k=='sleep' else None)
        for k in ['sleep','menstrual','wrist_temp','hrv','resting_hr','breathing']}
print(CycleSleepAnalyzer(data).run().summary())
"

Privacidad

Los datos de salud estan en .gitignore. El repo solo contiene codigo y datos sinteticos de ejemplo. Ningun dato personal se sube.

Licencia

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

redmoon-0.2.0.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

redmoon-0.2.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file redmoon-0.2.0.tar.gz.

File metadata

  • Download URL: redmoon-0.2.0.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for redmoon-0.2.0.tar.gz
Algorithm Hash digest
SHA256 245b7d29bbf2f0c178c4018fc3f63e376497d2486e4657bbfb0459c20068723f
MD5 19b267fe94274e43cb2c56900cc291f9
BLAKE2b-256 6a6dd784dc6e862000b7a86edf69977217929d73009aa9c6097be3100134a0c7

See more details on using hashes here.

File details

Details for the file redmoon-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: redmoon-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for redmoon-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e861d196580f5707a56b6785618f5210723e1a39bbe06fe228afcca62e2d8657
MD5 2e5af38e35eb88bc8c8f22ddae0b71f0
BLAKE2b-256 cafcc45918a04a4b9e499a6b027a26e8479067b4329ef5e6828fdca5aab1f044

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page