jaimalklyde commited on
Commit
0f7276e
·
verified ·
1 Parent(s): 5d22fc2

Update src/module/Indicateurs_DQ.py

Browse files
Files changed (1) hide show
  1. src/module/Indicateurs_DQ.py +124 -37
src/module/Indicateurs_DQ.py CHANGED
@@ -1,15 +1,24 @@
1
  """
2
- MODULE: DATA QUALITY DASHBOARD - VERSION AMÉLIORÉE
3
- ===================================================
4
  Responsabilité : Audit complet, détection d'anomalies, analyses spécifiques hospitalières.
5
  Style : Gotham UI + Analyses médicales avancées
6
 
7
- Améliorations :
8
- - Chargement direct depuis Excel (pas de filtrage ETL)
9
- - 6 sections complètes d'analyse DQ
10
- - Métriques hospitalières spécifiques
11
- - Visualisations enrichies
12
- - Analyses temporelles des anomalies
 
 
 
 
 
 
 
 
 
13
  """
14
 
15
  import streamlit as st
@@ -62,20 +71,79 @@ def safe_pct(num, den):
62
  # =====================================================
63
 
64
  @st.cache_data(ttl=3600)
65
- def load_excel_data_direct(file_path: str) -> dict:
66
  """
67
- Charge DIRECTEMENT depuis Excel sans passer par ETL.
68
  Garantit qu'aucune anomalie n'est filtrée.
 
 
 
 
 
 
 
69
  """
70
  sheets = {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  try:
72
  # Chargement de toutes les feuilles nécessaires
73
- sheets['patients'] = pd.read_excel(file_path, sheet_name='patients')
74
- sheets['sejours'] = pd.read_excel(file_path, sheet_name='sejours')
75
- sheets['ressources_jour'] = pd.read_excel(file_path, sheet_name='ressources_jour')
76
- sheets['stock_materiel_jour'] = pd.read_excel(file_path, sheet_name='stock_materiel_jour')
77
- sheets['admissions_jour'] = pd.read_excel(file_path, sheet_name='admissions_jour')
78
- sheets['scenarios_calendrier'] = pd.read_excel(file_path, sheet_name='scenarios_calendrier')
79
 
80
  # Conversion des dates
81
  for sheet_name, df in sheets.items():
@@ -89,8 +157,9 @@ def load_excel_data_direct(file_path: str) -> dict:
89
  df['date_naissance'] = pd.to_datetime(df['date_naissance'], errors='coerce')
90
 
91
  return sheets
 
92
  except Exception as e:
93
- st.error(f"❌ Erreur chargement Excel : {str(e)}")
94
  return {}
95
 
96
 
@@ -428,31 +497,48 @@ def plot_completeness_radar(analyzer: HospitalDataQualityAnalyzer):
428
  # ================= DASHBOARD PRINCIPAL ===============
429
  # =====================================================
430
 
431
- def show_enhanced_dq_dashboard():
432
  """
433
- Dashboard Data Quality amélioré avec toutes les sections.
 
 
 
 
434
  """
435
  st.markdown("## 🛡️ CENTRE DE CONTRÔLE DATA QUALITY")
436
  st.caption("Analyse complète de la qualité des données hospitalières")
437
 
438
- # ================= UPLOAD FICHIER =================
439
- st.sidebar.header("⚙️ Configuration")
440
-
441
- uploaded_file = st.sidebar.file_uploader(
442
- "Charger le fichier Excel",
443
- type=['xlsx'],
444
- help="Fichier bdd_mvp_faker.xlsx"
445
- )
446
 
447
- if uploaded_file is None:
448
- st.info("👈 Veuillez charger le fichier Excel dans la barre latérale")
449
- return
 
 
 
 
450
 
451
- # ================= CHARGEMENT =================
452
- with st.spinner("🔄 Chargement des données..."):
453
- dataframes = load_excel_data_direct(uploaded_file)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
 
455
- if not dataframes:
 
456
  st.error("❌ Erreur lors du chargement des données")
457
  return
458
 
@@ -460,7 +546,8 @@ def show_enhanced_dq_dashboard():
460
  analyzer = HospitalDataQualityAnalyzer(dataframes)
461
  scores = analyzer.compute_global_score()
462
 
463
- st.success(f"✅ Données chargées : {sum(m['total'] for m in analyzer.metrics.values()):,} lignes au total")
 
464
 
465
  # ==================================================
466
  # ================= KPI GLOBAUX ====================
@@ -748,7 +835,7 @@ def show_enhanced_dq_dashboard():
748
 
749
  with col2:
750
  # Export des anomalies détectées
751
- if metrics['patients']['anomalies'] > 0:
752
  anomalies_df = analyzer.df_pat[analyzer.df_pat['dq_is_anomaly'] == 1][
753
  ['patient_id', 'nom', 'prenom', 'dq_anomaly_type', 'dq_anomaly_detail']
754
  ]
@@ -763,4 +850,4 @@ def show_enhanced_dq_dashboard():
763
 
764
  # Point d'entrée
765
  if __name__ == "__main__":
766
- show_enhanced_dq_dashboard()
 
1
  """
2
+ MODULE: DATA QUALITY DASHBOARD - VERSION COMPLÈTE
3
+ ==================================================
4
  Responsabilité : Audit complet, détection d'anomalies, analyses spécifiques hospitalières.
5
  Style : Gotham UI + Analyses médicales avancées
6
 
7
+ Fonctionnalités :
8
+ - ✅ Accès Google Sheets (via client)
9
+ - ✅ Upload fichier Excel local
10
+ - ✅ 6 sections complètes d'analyse DQ
11
+ - ✅ Métriques hospitalières spécifiques
12
+ - ✅ Visualisations enrichies
13
+ - ✅ Analyses temporelles des anomalies
14
+ - ✅ Recommandations automatiques
15
+ - ✅ Export rapports CSV
16
+
17
+ Améliorations vs version originale :
18
+ - Chargement direct (pas de filtrage ETL) pour voir toutes les anomalies
19
+ - 6 sections au lieu de 2
20
+ - Analyses spécifiques au contexte hospitalier
21
+ - Visualisations interactives avancées
22
  """
23
 
24
  import streamlit as st
 
71
  # =====================================================
72
 
73
  @st.cache_data(ttl=3600)
74
+ def load_from_google_sheets(client, sheet_name: str) -> dict:
75
  """
76
+ Charge les données depuis Google Sheets SANS passer par ETL.
77
  Garantit qu'aucune anomalie n'est filtrée.
78
+
79
+ Args:
80
+ client: Client Google Sheets
81
+ sheet_name: Nom de la feuille Google Sheets
82
+
83
+ Returns:
84
+ Dictionnaire de DataFrames
85
  """
86
  sheets = {}
87
+
88
+ try:
89
+ # Liste des feuilles à charger
90
+ sheet_names = [
91
+ 'patients', 'sejours', 'ressources_jour',
92
+ 'stock_materiel_jour', 'admissions_jour', 'scenarios_calendrier'
93
+ ]
94
+
95
+ for name in sheet_names:
96
+ try:
97
+ # Récupération directe depuis Google Sheets
98
+ worksheet = client.open(sheet_name).worksheet(name)
99
+ data = worksheet.get_all_records()
100
+ df = pd.DataFrame(data)
101
+
102
+ # Conversion des dates
103
+ if 'date' in df.columns:
104
+ df['date'] = pd.to_datetime(df['date'], errors='coerce')
105
+ if 'date_entree' in df.columns:
106
+ df['date_entree'] = pd.to_datetime(df['date_entree'], errors='coerce')
107
+ if 'date_sortie' in df.columns:
108
+ df['date_sortie'] = pd.to_datetime(df['date_sortie'], errors='coerce')
109
+ if 'date_naissance' in df.columns:
110
+ df['date_naissance'] = pd.to_datetime(df['date_naissance'], errors='coerce')
111
+
112
+ sheets[name] = df
113
+
114
+ except Exception as e:
115
+ st.warning(f"⚠️ Impossible de charger la feuille '{name}': {str(e)}")
116
+ continue
117
+
118
+ return sheets
119
+
120
+ except Exception as e:
121
+ st.error(f"❌ Erreur lors du chargement depuis Google Sheets : {str(e)}")
122
+ return {}
123
+
124
+
125
+ @st.cache_data(ttl=3600)
126
+ def load_from_excel_file(file) -> dict:
127
+ """
128
+ Charge les données depuis un fichier Excel uploadé.
129
+ Garantit qu'aucune anomalie n'est filtrée.
130
+
131
+ Args:
132
+ file: Fichier uploadé via st.file_uploader
133
+
134
+ Returns:
135
+ Dictionnaire de DataFrames
136
+ """
137
+ sheets = {}
138
+
139
  try:
140
  # Chargement de toutes les feuilles nécessaires
141
+ sheets['patients'] = pd.read_excel(file, sheet_name='patients')
142
+ sheets['sejours'] = pd.read_excel(file, sheet_name='sejours')
143
+ sheets['ressources_jour'] = pd.read_excel(file, sheet_name='ressources_jour')
144
+ sheets['stock_materiel_jour'] = pd.read_excel(file, sheet_name='stock_materiel_jour')
145
+ sheets['admissions_jour'] = pd.read_excel(file, sheet_name='admissions_jour')
146
+ sheets['scenarios_calendrier'] = pd.read_excel(file, sheet_name='scenarios_calendrier')
147
 
148
  # Conversion des dates
149
  for sheet_name, df in sheets.items():
 
157
  df['date_naissance'] = pd.to_datetime(df['date_naissance'], errors='coerce')
158
 
159
  return sheets
160
+
161
  except Exception as e:
162
+ st.error(f"❌ Erreur lors du chargement du fichier Excel : {str(e)}")
163
  return {}
164
 
165
 
 
497
  # ================= DASHBOARD PRINCIPAL ===============
498
  # =====================================================
499
 
500
+ def show_dq_dashboard(client=None, sheet_name=None):
501
  """
502
+ Dashboard Data Quality complet avec support Google Sheets et Upload Fichier.
503
+
504
+ Args:
505
+ client: Client Google Sheets (optionnel)
506
+ sheet_name: Nom de la feuille Google Sheets (optionnel)
507
  """
508
  st.markdown("## 🛡️ CENTRE DE CONTRÔLE DATA QUALITY")
509
  st.caption("Analyse complète de la qualité des données hospitalières")
510
 
511
+ dataframes = None
 
 
 
 
 
 
 
512
 
513
+ # ================= MODE DE CHARGEMENT =================
514
+ if client is not None and sheet_name is not None:
515
+ # Mode Google Sheets (prioritaire si client fourni)
516
+ st.info("📊 **Mode : Google Sheets**")
517
+
518
+ with st.spinner("🔄 Chargement depuis Google Sheets..."):
519
+ dataframes = load_from_google_sheets(client, sheet_name)
520
 
521
+ else:
522
+ # Mode Upload Fichier
523
+ st.sidebar.header("⚙️ Configuration")
524
+
525
+ uploaded_file = st.sidebar.file_uploader(
526
+ "Charger le fichier Excel",
527
+ type=['xlsx'],
528
+ help="Fichier bdd_mvp_faker.xlsx"
529
+ )
530
+
531
+ if uploaded_file is not None:
532
+ st.info("📁 **Mode : Fichier Excel Local**")
533
+
534
+ with st.spinner("🔄 Chargement du fichier Excel..."):
535
+ dataframes = load_from_excel_file(uploaded_file)
536
+ else:
537
+ st.info("👈 Veuillez charger le fichier Excel dans la barre latérale")
538
+ return
539
 
540
+ # ================= VÉRIFICATION CHARGEMENT =================
541
+ if not dataframes or len(dataframes) == 0:
542
  st.error("❌ Erreur lors du chargement des données")
543
  return
544
 
 
546
  analyzer = HospitalDataQualityAnalyzer(dataframes)
547
  scores = analyzer.compute_global_score()
548
 
549
+ total_lignes = sum(m['total'] for m in analyzer.metrics.values())
550
+ st.success(f"✅ Données chargées : **{total_lignes:,}** lignes au total")
551
 
552
  # ==================================================
553
  # ================= KPI GLOBAUX ====================
 
835
 
836
  with col2:
837
  # Export des anomalies détectées
838
+ if metrics['patients']['anomalies'] > 0 and analyzer.df_pat is not None:
839
  anomalies_df = analyzer.df_pat[analyzer.df_pat['dq_is_anomaly'] == 1][
840
  ['patient_id', 'nom', 'prenom', 'dq_anomaly_type', 'dq_anomaly_detail']
841
  ]
 
850
 
851
  # Point d'entrée
852
  if __name__ == "__main__":
853
+ show_dq_dashboard()