001_05 — Analyse par classes avec pandas DataFrame

Cahier des charges

1
Dans le fichier 001_05.py, je veux la même structure df, mais je souhaite montrer les possibilités des dataframes pour extraire des données et faire des calculs : 
2
3
La feuille qui contient les donnée sera nommée do
4
1. regrouper les données en 4 classes de longueur fixes et égales, 
5
2. compter le nombre de points à l'intérieur des classes
6
3. construire un deuxième dataframe avec les classes dans une autre feuille nommée do_classes
7

Code Python

1
# TD_EDC_01_001_05.py
2
# Résumé : Utilise pandas DataFrame pour créer des classes et analyser les données
3
# Génère deux feuilles : "do" avec les données brutes, "do_classes" avec le regroupement par classes
4
from pathlib import Path
5
import subprocess
6
import pandas as pd
7
import xlsxwriter
8
9
10
def build_paths() -> Path:
11
    """Calcule le chemin du fichier Excel de sortie."""
12
    script = Path(__file__).resolve()
13
    root = script.parent.parent
14
    stem = script.stem
15
    base_dir_name = script.parent.name
16
    xlsx_dir = root / f"{base_dir_name}_do"
17
    xlsx_dir.mkdir(parents=True, exist_ok=True)
18
    
19
    xlsx_path = (xlsx_dir / f"{stem}.xlsx").resolve()
20
    return xlsx_path
21
22
23
def delete_if_exists(file_path: Path) -> None:
24
    """Supprime le fichier s'il existe déjà."""
25
    if file_path.exists():
26
        file_path.unlink()
27
28
29
def prepare_data(n: int = 9, ttf_values: list = None) -> pd.DataFrame:
30
    """Prépare les données sous forme de DataFrame pandas."""
31
    
32
    # Créer les colonnes
33
    i_values = list(range(n + 1))
34
    
35
    # Calculer dN(i) : 0 pour i=0, puis 1 pour i≥1
36
    dN_values = [0] + [1] * n
37
    
38
    # Calculer N(i) : commence à n et décrémente de dN(i)
39
    N_values = [n - i for i in range(n + 1)]
40
    
41
    # Créer le DataFrame
42
    df = pd.DataFrame({
43
        'i': i_values,
44
        'ttf(i)': ttf_values if ttf_values else [0] * (n + 1),
45
        'dN(i)': dN_values,
46
        'N(i)': N_values
47
    })
48
    
49
    return df
50
51
52
def create_classes_dataframe(df: pd.DataFrame, n_classes: int = 4) -> pd.DataFrame:
53
    """Crée un DataFrame avec regroupement par classes de ttf(i)."""
54
    
55
    # Extraire la colonne ttf(i)
56
    ttf_values = df['ttf(i)']
57
    
58
    # Déterminer les bornes des classes (longueurs fixes et égales)
59
    min_val = ttf_values.min()
60
    max_val = ttf_values.max()
61
    class_width = (max_val - min_val) / n_classes
62
    
63
    # Créer les bornes des classes
64
    bins = [min_val + i * class_width for i in range(n_classes + 1)]
65
    
66
    # Créer les labels des classes
67
    labels = [f"[{bins[i]:.0f}, {bins[i+1]:.0f})" for i in range(n_classes)]
68
    
69
    # Catégoriser les valeurs ttf(i) en classes
70
    df['classe'] = pd.cut(ttf_values, bins=bins, labels=labels, include_lowest=True)
71
    
72
    # Compter le nombre de points dans chaque classe
73
    class_counts = df['classe'].value_counts().sort_index()
74
    
75
    # Créer le DataFrame des classes
76
    df_classes = pd.DataFrame({
77
        'Classe': class_counts.index,
78
        'Borne_inf': [bins[i] for i in range(n_classes)],
79
        'Borne_sup': [bins[i+1] for i in range(n_classes)],
80
        'Nombre_points': class_counts.values,
81
        'Largeur': [class_width] * n_classes
82
    })
83
    
84
    return df_classes
85
86
87
def write_dataframes_to_excel(xlsx_path: Path, df: pd.DataFrame, df_classes: pd.DataFrame) -> None:
88
    """Écrit les deux DataFrames dans le fichier Excel avec xlsxwriter."""
89
    
90
    # Créer le classeur
91
    workbook = xlsxwriter.Workbook(str(xlsx_path))
92
    
93
    # Feuille 1 : "do" avec les données brutes
94
    worksheet_do = workbook.add_worksheet("do")
95
    
96
    # Écrire les en-têtes pour "do"
97
    for col_num, col_name in enumerate(df.columns):
98
        worksheet_do.write(0, col_num, col_name)
99
    
100
    # Écrire les données pour "do"
101
    for row_num, row_data in enumerate(df.values, start=1):
102
        for col_num, value in enumerate(row_data):
103
            # Gérer les catégories pandas (classe)
104
            if isinstance(value, pd.Interval):
105
                worksheet_do.write(row_num, col_num, str(value))
106
            else:
107
                worksheet_do.write(row_num, col_num, value)
108
    
109
    print(f"✓ DataFrame 'do' écrit avec {len(df)} lignes")
110
    
111
    # Feuille 2 : "do_classes" avec le regroupement par classes
112
    worksheet_classes = workbook.add_worksheet("do_classes")
113
    
114
    # Écrire les en-têtes pour "do_classes"
115
    for col_num, col_name in enumerate(df_classes.columns):
116
        worksheet_classes.write(0, col_num, col_name)
117
    
118
    # Écrire les données pour "do_classes"
119
    for row_num, row_data in enumerate(df_classes.values, start=1):
120
        for col_num, value in enumerate(row_data):
121
            # Gérer les catégories pandas
122
            if isinstance(value, pd.Interval):
123
                worksheet_classes.write(row_num, col_num, str(value))
124
            else:
125
                worksheet_classes.write(row_num, col_num, value)
126
    
127
    print(f"✓ DataFrame 'do_classes' écrit avec {len(df_classes)} classes")
128
    
129
    workbook.close()
130
131
132
def open_in_excel(xlsx_path: Path) -> None:
133
    """Ouvre le classeur généré dans Excel."""
134
    subprocess.Popen(["start", "excel", str(xlsx_path)], shell=True)
135
136
137
def main() -> None:
138
    """Pipeline : prépare les données, crée les classes, écrit dans Excel."""
139
    xlsx_path = build_paths()
140
    
141
    # Données d'entrée
142
    ttf_i = [0, 250, 400, 550, 700, 850, 1000, 1150, 1300, 1450]
143
    
144
    # Étape 1 : Préparer les données dans un DataFrame
145
    df = prepare_data(n=9, ttf_values=ttf_i)
146
    
147
    print("Données préparées :")
148
    print(df)
149
    print()
150
    
151
    # Étape 2 : Créer le DataFrame des classes
152
    df_classes = create_classes_dataframe(df, n_classes=4)
153
    
154
    print("Classes créées :")
155
    print(df_classes)
156
    print()
157
    
158
    # Étape 3 : Écrire les deux DataFrames dans Excel
159
    delete_if_exists(xlsx_path)
160
    write_dataframes_to_excel(xlsx_path, df, df_classes)
161
    
162
    print(f"Fichier créé : {xlsx_path}")
163
    open_in_excel(xlsx_path)
164
165
166
if __name__ == "__main__":
167
    main()
168

Documentation

1
# 001_05 — Analyse par classes avec pandas DataFrame
2
3
## Objectifs
4
5
- Démontrer les capacités d'analyse des DataFrames pandas.
6
- Regrouper les données ttf(i) en 4 classes de longueur fixe et égale.
7
- Compter le nombre de points dans chaque classe.
8
- Générer deux feuilles Excel : "do" (données brutes) et "do_classes" (analyse).
9
10
## Fonctionnement
11
12
1. **Préparation** : `prepare_data()` crée le DataFrame avec i, ttf(i), dN(i), N(i).
13
2. **Création des classes** : `create_classes_dataframe()` utilise `pd.cut()` pour découper ttf(i) en 4 intervalles égaux.
14
3. **Comptage** : `.value_counts()` compte les points dans chaque classe.
15
4. **Écriture** : `write_dataframes_to_excel()` génère les deux feuilles avec xlsxwriter.
16
17
## Points techniques pandas
18
19
### pd.cut() - Découpage en classes
20
21
```python
22
df['classe'] = pd.cut(ttf_values, bins=bins, labels=labels, include_lowest=True)
23
```
24
25
- Crée des intervalles de largeur égale
26
- `bins` : Liste des bornes [0, 362.5, 725, 1087.5, 1450]
27
- `labels` : Noms des classes `["[0, 362)", "[362, 725)", ...]`
28
- `include_lowest=True` : Inclut la borne inférieure dans la première classe
29
30
### value_counts() - Comptage par catégorie
31
32
```python
33
class_counts = df['classe'].value_counts().sort_index()
34
```
35
36
- Compte automatiquement les occurrences de chaque classe
37
- `sort_index()` : Tri par ordre des classes
38
39
### Calcul de largeur de classe
40
41
```python
42
class_width = (max_val - min_val) / n_classes
43
# (1450 - 0) / 4 = 362.5
44
```
45
46
## Structure des feuilles Excel
47
48
### Feuille "do"
49
50
Colonnes : i, ttf(i), dN(i), N(i), classe
51
- Contient toutes les données brutes (10 lignes)
52
- Colonne "classe" ajoutée avec l'intervalle d'appartenance
53
54
### Feuille "do_classes"
55
56
Colonnes : Classe, Borne_inf, Borne_sup, Nombre_points, Largeur
57
58
- Résumé statistique (4 lignes, une par classe)
59
- Exemple :
60
  - [0, 362) : 2 points (ttf=0, 250)
61
  - [362, 725) : 3 points (ttf=400, 550, 700)
62
  - [725, 1088) : 2 points (ttf=850, 1000)
63
  - [1088, 1450) : 3 points (ttf=1150, 1300, 1450)
64
65
## Utilisation
66
67
```bash
68
python 001/001_05.py
69
```
70
71
Fichier produit : `001_do/001_05.xlsx` avec feuilles "do" et "do_classes".
72
73
## Concepts pandas démontrés
74
75
- **Catégorisation** : Transformation de valeurs continues en catégories discrètes
76
- **Agrégation** : Comptage et regroupement de données
77
- **Création de DataFrame** : Construction d'un nouveau DataFrame à partir d'analyses
78
- **Manipulation de colonnes** : Ajout de colonnes calculées
79