- Apprendre
- Informatique et numérique
- Science des données et IA
- Python et pandas : NumPy, analyse et visualisation de données
- Séries chronologiques avec pandas
Dates et séries chronologiques avec pandas
IntermédiaireUnité 6 sur 8 de la formation Formation : Python et pandas : NumPy, analyse et visualisation de données
Ce que tu vas apprendre
- Stocke des instants et des durées dans les types datetime de pandas, convertis des dates textuelles sans confondre le jour et le mois, et extrais des composantes calendaires comme le mois et le jour de la semaine.
- Travailler avec les horodatages, les durées et les composantes calendairesUtilise Timestamp, Timedelta et le type de données datetime64, calcule le temps entre des événements et extrais des composantes comme l’année, l’heure et le jour de la semaine avec l’accesseur
.dt. - Convertir des dates textuelles et les mettre en forme pour la sortieConvertis du texte et des nombres en valeurs datetime avec
pd.to_datetime, choisis des formats qui ne permutent jamais le jour et le mois, traite les valeurs impossibles à convertir et transforme les valeurs datetime en texte lisible.
- Travailler avec les horodatages, les durées et les composantes calendaires
- Construis un index temporel propre et trié, utilise-le pour sélectionner un jour, un mois ou une plage horaire, et compare chaque valeur aux précédentes.
- Construire et vérifier un index temporelTransforme une colonne datetime en DatetimeIndex trié, traite les horodatages en double et recherche les lacunes et la fréquence d’une série.
- Sélectionner les lignes selon la date et l’heureSélectionne des années, des mois, des jours et des intervalles entiers avec des chaînes de dates, filtre par jour de la semaine ou par heure et évite les erreurs qui renvoient les mauvaises lignes.
- Comparer les valeurs au fil du temps à l’aide de décalages, de différences et de variations en pourcentageDécale les valeurs vers le passé ou l’avenir, calcule des variations et des taux de croissance, et comprends comment pandas aligne deux séries chronologiques par date.
- Construire et vérifier un index temporel
- Crée des séquences régulières de dates, décale des dates selon des règles calendaires comme « un mois plus tard » ou « le jour ouvré suivant », et représente des mois, des trimestres et des exercices entiers par des périodes.
- Créer des séquences régulières de dates avec des alias de fréquenceGénère des séquences de dates et d’heures avec
pd.date_range, choisis l’alias de fréquence approprié et obtiens les bonnes dates de début et de fin. - Décaler des dates selon les règles du calendrierDistingue les durées fixes des règles calendaires et utilise DateOffset, les décalages de fin de mois, de jour ouvré et d’autres décalages pour déplacer correctement les dates.
- Représenter des mois, des trimestres et des exercices entiers par des périodesReprésente des durées avec Period et PeriodIndex, convertis les horodatages en périodes et inversement, et traite les trimestres d’un exercice.
- Créer des séquences régulières de dates avec des alias de fréquence
- Agrège des données détaillées en totaux et moyennes par jour, semaine, mois ou trimestre, complète une grille temporelle plus fine et rééchantillonne plusieurs séries à la fois.
- Sous-échantillonner pour calculer des totaux, des valeurs typiques et d’autres indicateursUtilise
resamplepour agréger les données dans des intervalles temporels plus larges, choisis l’agrégation appropriée et lis correctement les bornes et les étiquettes des intervalles. - Suréchantillonner et combler les lacunes d’une série chronologiquePasse les données à une grille temporelle plus fine, remplis les nouveaux créneaux en propageant des valeurs vers l’avant ou l’arrière ou par interpolation, et fais apparaître les dates manquantes.
- Rééchantillonner plusieurs séries à la fois par groupeRééchantillonne par groupe une table au format long contenant de nombreux magasins, capteurs ou clients, puis remodèle le résultat pour les comparer.
- Sous-échantillonner pour calculer des totaux, des valeurs typiques et d’autres indicateurs
- Calcule des moyennes mobiles et d’autres statistiques sur des fenêtres définies par un nombre de lignes ou une durée, ainsi que des sommes cumulées et des moyennes pondérées qui tiennent compte de tout l’historique.
- Calculer des statistiques glissantes sur un nombre fixe de lignesUtilise
rolling(n)pour calculer des moyennes mobiles, des sommes et d’autres statistiques, maîtrise le traitement des fenêtres incomplètes et applique des fenêtres par groupe. - Utiliser des fenêtres temporelles pour des données irrégulièresDéfinis les fenêtres par une durée comme « 7D », comprends quelles observations chaque fenêtre inclut et choisis entre les fenêtres définies par un nombre de lignes et les fenêtres temporelles.
- Suivre les sommes cumulées, les maximums cumulés et les moyennes à pondération exponentielleUtilise des fenêtres croissantes pour calculer des statistiques cumulées et des drawdowns, ainsi que des moyennes à pondération exponentielle qui donnent plus de poids aux valeurs récentes.
- Calculer des statistiques glissantes sur un nombre fixe de lignes
- Associe le bon fuseau horaire aux horodatages, convertis-les entre fuseaux, combine des données provenant de fuseaux différents et traite les heures sautées ou répétées lors du passage à l’heure d’été.
- Localiser les horodatages et les convertir entre fuseaux horairesDistingue les horodatages sans fuseau horaire de ceux qui en possèdent un, associe un fuseau avec
tz_localize, convertis avectz_convertet combine des données enregistrées dans différents fuseaux. - Gérer l’heure d’été dans les séries chronologiquesReconnais les heures locales sautées et répétées, localise-les en connaissance de cause, puis rééchantillonne et décale correctement les données les jours de 23 ou 25 heures.
- Localiser les horodatages et les convertir entre fuseaux horaires
Séries chronologiques avec pandas : cours
1Convertir les dates et les heures en données utilisables dans les calculs de pandas
Les dates arrivent sous forme de chaînes, de nombres et d’heures affichées, mais l’analyse nécessite une représentation cohérente. Apprends à transformer ces entrées en instants et en durées, à vérifier les conversions échouées et à extraire des composantes calendaires utiles. Les exemples distinguent une valeur datetime stockée de son texte d’affichage, afin que les tris, sélections et calculs ultérieurs tiennent compte du calendrier. De petits détails comme les codes de format du mois et de la minute ou la résolution de stockage peuvent modifier fortement un résultat.
1.1 Travailler avec les horodatages, les durées et les composantes calendaires
Une date est plus utile lorsque pandas sait qu’il s’agit d’une date. Une série chronologique associe des observations à des instants ou à des durées. Des relevés horaires d’énergie forment une série régulière ; des commandes arrivant à intervalles irréguliers forment une série irrégulière. Un texte comme « 12/31/2024 » peut se trier après « 03/01/2025 », alors que décembre est antérieur. Des chaînes ISO complètes et cohérentes se trient correctement, mais les valeurs datetime permettent aussi de sélectionner des dates et de faire des calculs calendaires.
Choisir le bon objet temporel
Python fournit datetime, date et timedelta. Dans pandas, un Timestamp contient un instant, une colonne datetime possède un type de données datetime64[unit], et un DatetimeIndex contient des étiquettes de lignes datetime. NaT désigne un instant manquant. Détecte-le avec pd.isna() ; soustraire un instant manquant produit une autre valeur manquante.
L’unité dans datetime64[us] est la microseconde : c’est la résolution de stockage. Les autres unités comprennent les secondes (s), les millisecondes (ms) et les nanosecondes (ns). pandas 3 convertit normalement le texte avec une résolution à la microseconde et utilise les nanosecondes lorsque le texte l’exige. Une résolution plus fine utilise une plus grande partie de la plage des entiers : les dates en nanosecondes ne vont que de 1677 à 2262.
Calculer le temps écoulé
import pandas as pd
start = pd.Timestamp("2025-03-10 18:00")
end = pd.Timestamp("2025-03-14 09:30")
elapsed = end - start
hours = elapsed / pd.Timedelta(hours=1)
elapsed correspond à 3 jours, 15 heures et 30 minutes. Les trois jours représentent 72 heures, donc hours vaut 87,5. elapsed.total_seconds() donne 315 000. Son attribut .days ne donne que 3 ; c’est la composante en jours entiers, pas la durée complète en jours. Crée des durées avec pd.Timedelta(hours=36) ou convertis-en plusieurs avec pd.to_timedelta(["1h", "90min"]).
Soustraire un horodatage à toute une colonne datetime produit des durées ligne par ligne. Utilise .dt.days pour les composantes en jours entiers ou divise la colonne de durées par un Timedelta représentant une unité pour obtenir des totaux fractionnaires.
Extraire les composantes calendaires et arrondir les heures
Sur une colonne, .dt.year, .dt.month, .dt.hour et .dt.quarter extraient des composantes calendaires. .dt.day_of_week numérote les jours de 0 pour lundi à 6 pour dimanche ; .dt.day_name() donne un nom. Le 14 mars 2025 est un vendredi, numéroté 4. Un index utilise directement ces attributs : df.index.month. Les graphies day_of_week et day_of_year remplacent les anciennes graphies devenues obsolètes dans pandas 3.1.
Un jour de la semaine peut devenir une clé de regroupement : df.groupby(df["timestamp"].dt.day_name())["kwh"].mean(). Regrouper par numéro de mois réunit ce mois sur plusieurs années ; une période mensuelle garde chaque année distincte.
Pour 09 h 37, .dt.floor("h") donne 09 h, .dt.ceil("h") donne 10 h et .dt.round("15min") donne 09 h 30. .dt.normalize() fixe les heures à minuit tout en conservant des valeurs datetime. .dt.date produit quant à lui des objets date Python et perd les fonctionnalités des colonnes datetime.
Indiquer explicitement les unités numériques
astype("int64") renvoie des décomptes dans l’unité propre à la colonne. Un décompte en microsecondes est 1 000 fois plus petit que le décompte en nanosecondes pour le même instant. Si un calcul externe nécessite des nanosecondes, utilise s.dt.as_unit("ns").astype("int64") ; un Timestamp ou un index utilise directement .as_unit("ns"). Pour le temps écoulé, les calculs sur les Timedelta évitent ce piège lié aux unités.
Points clés
- Un Timestamp représente un instant ; un Timedelta représente une durée écoulée.
- Utilise des Timedelta représentant une unité pour obtenir des durées complètes, y compris leurs fractions.
- Les attributs calendaires utilisent
.dtsur les colonnes et un accès direct sur les index. - Les instants manquants sont représentés par
NaT. - Les décomptes entiers des valeurs datetime dépendent de la résolution de stockage.
1.2 Convertir des dates textuelles et les mettre en forme pour la sortie
La conversion donne un sens calendaire au texte. Avant de convertir une colonne de dates, détermine son format et vérifie si elle contient des décalages, des entrées invalides ou des valeurs manquantes. ISO 8601 écrit l’année en premier, comme dans « 2025-03-14T09:30:00 », et évite l’ambiguïté entre le jour et le mois.
Indiquer le format d’origine
« 03/04/2025 » peut désigner le 4 mars ou le 3 avril. pd.to_datetime("03/04/2025") lit le mois en premier ; dayfirst=True lit le jour en premier. Un format connu est plus clair :
raw = pd.Series(["14/03/2025 18:45", "15/03/2025 09:00"])
parsed = pd.to_datetime(raw, format="%d/%m/%Y %H:%M")
%Y représente une année à quatre chiffres, %m un mois et %d un jour. %H représente une heure sur 24 heures, %M une minute et %S une seconde. Utilise %I avec %p pour une horloge sur 12 heures et AM/PM. %b et %B lisent les noms de mois abrégés et complets. %M en majuscule désigne les minutes : il ne peut donc pas remplacer %m en minuscule pour les mois.
Sans format, pandas infère un format à partir de la première entrée non manquante et l’applique à la colonne. Si « 03/04/2025 » est en premier, la conversion d’un « 13/04/2025 » ultérieur échoue avec le format inféré qui place le mois en premier. Modifier l’ordre des lignes peut changer le format inféré. format="ISO8601" traite les variantes ISO. format="mixed" convertit les entrées individuellement, mais ne peut pas résoudre une convention d’origine ambiguë ; clarifie ou vérifie d’abord cette convention.
Examiner les conversions échouées
raw = pd.Series(["2025-01-15", "not a date", None])
parsed = pd.to_datetime(raw, format="%Y-%m-%d", errors="coerce")
failed = parsed.isna() & raw.notna()
Le résultat contient le 15 janvier et deux valeurs NaT. parsed.isna().sum() vaut 2 car il inclut l’entrée déjà manquante. failed.sum() vaut 1 car seule « not a date » était présente et n’a pas pu être convertie. Examine raw[failed] avant de décider de la corriger ou de la supprimer. La coercition permet au chargement de continuer, mais masque aussi les fautes de frappe comme un mois impossible. La valeur par défaut errors="raise" arrête le traitement en cas d’entrée invalide ; pandas 3 a supprimé errors="ignore".
Convertir les dates des fichiers et les horodatages numériques
pd.read_csv("meter.csv", parse_dates=["timestamp"], index_col="timestamp") demande la conversion des dates et la création d’un index temporel. Vérifie les types de données obtenus après le chargement. Les colonnes textuelles utilisent le type str dans pandas 3 ; les versions précédentes affichent couramment object.
Réunis les chaînes de date et d’heure séparées avec un espace avant la conversion. Les colonnes nommées year, month et day peuvent être assemblées directement avec pd.to_datetime(df[["year", "month", "day"]]).
Pour les décomptes Unix, précise l’unité. pd.to_datetime(1735689600, unit="s", utc=True) donne minuit UTC le 1er janvier 2025. Le décompte en millisecondes est 1735689600000 avec unit="ms". Utiliser la mauvaise unité change l’instant interprété.
Mettre en forme uniquement pour la présentation
parsed.dt.strftime("%d %b %Y") écrit du texte comme « 15 Jan 2025 ». La méthode .isoformat() d’un Timestamp écrit une chaîne ISO. Les noms de mois et de jours suivent les paramètres régionaux du système ; les exemples affichés utilisent l’anglais. Conserve les valeurs datetime pendant l’analyse et mets-les en forme à l’exportation, car les chaînes ne permettent plus les calculs sur les dates.
Points clés
- Privilégie les dates ISO non ambiguës lorsque tu maîtrises la source.
- Indique explicitement un format d’analyse des dates connu.
- Distingue les entrées invalides des valeurs déjà manquantes.
- Associe les décomptes Unix à leur unité, secondes ou millisecondes.
- Mets les dates sous forme de texte à la fin de l’analyse.
%mdésigne le mois ;%Mdésigne la minute.
2Indexer, sélectionner et comparer les données selon le temps
Un index temporel permet d’utiliser les dates comme étiquettes de lignes, mais ces étiquettes doivent être vérifiées avec soin avant toute comparaison. Trie les observations, détermine le sens des horodatages en double et fais apparaître les dates manquantes. Sélectionne ensuite des périodes calendaires ou des plages horaires récurrentes et compare les valeurs aux précédentes. La distinction centrale concerne la position des lignes et le temps réel : une ligne précédente peut remonter à plusieurs jours, et deux séries se combinent en faisant correspondre leurs horodatages.
2.1 Construire et vérifier un index temporel
Un index temporel utile est converti, trié et vérifié. Une table peut contenir plusieurs événements à un même instant, des jours manquants ou des lots dans le désordre. Chacune de ces situations modifie le sens des calculs ultérieurs.
Construire des étiquettes de lignes datetime
df["timestamp"] = pd.to_datetime(df["timestamp"], format="%Y-%m-%d %H:%M")
df = df.set_index("timestamp").sort_index()
set_index() déplace la colonne dans les étiquettes de lignes ; il ne convertit pas le texte. Examine df.index.dtype pour vérifier le type datetime et df.index.is_monotonic_increasing pour vérifier l’ordre chronologique. Des instants voisins égaux sont autorisés dans un index croissant : ce contrôle n’établit donc pas l’unicité.
Un DatetimeIndex permet la sélection par date et le rééchantillonnage. Des étiquettes textuelles ne deviennent pas un index temporel simplement parce qu’elles ressemblent à des dates. Tu peux aussi laisser les horodatages dans une colonne : df.resample("D", on="timestamp") utilise cette colonne sans modifier l’index. Un PeriodIndex est une autre représentation des séries chronologiques lorsque les lignes décrivent des périodes comme des mois.
Déterminer le sens des heures répétées
df.index.is_unique indique si chaque étiquette est distincte. df.index.duplicated() marque les étiquettes répétées après la première occurrence. Supposons que deux relevés, 3 et 5, partagent la date du 1er janvier et qu’un relevé de 4 corresponde au 2 janvier. Calculer la moyenne des relevés en double avec df.groupby(level=0).mean() produit 4,0 aux deux dates.
Cette opération implique une décision sur les données. Si les lignes représentent des achats distincts, leur somme peut convenir. Si une importation a créé un enregistrement en double, conserver la dernière copie avec df[~df.index.duplicated(keep="last")] peut convenir. Ne supprime pas des transactions valides simplement pour rendre un index unique. Les opérations qui placent une valeur à chaque étiquette cible, notamment reindex() et asfreq(), nécessitent des étiquettes sources uniques.
Distinguer fréquence stockée et fréquence inférée
Un index créé par pd.date_range() possède normalement .freq. Pour des horodatages convertis, .freq vaut souvent None, même s’ils correspondent à des jours consécutifs. pd.infer_freq(df.index) examine au moins trois horodatages et renvoie un alias comme « D » ou « ME » s’il trouve une régularité. Un espacement irrégulier renvoie None.
Les métadonnées de fréquence ne permettent pas de vérifier à elles seules que les données sont complètes. Pour rechercher les lignes quotidiennes absentes, construis le calendrier attendu :
calendar = pd.date_range(df.index.min(), df.index.max(), freq="D")
missing = calendar.difference(df.index)
Un jour manquant n’a pas de ligne. Il se distingue d’une ligne présente contenant NaN. Un calendrier borné par le minimum et le maximum observés ne peut pas révéler les dates manquantes en dehors de cette plage ; utilise les dates de début et de fin prévues pour le compte rendu lorsqu’elles sont connues.
Préparer les opérations ultérieures
Le tri rend les tranches prévisibles et est nécessaire aux fenêtres glissantes temporelles. Les lignes manquantes comptent même lorsqu’un calcul réussit : shift(1) signifie une ligne en arrière et rolling(7) signifie sept lignes. Aucun des deux ne vérifie que chaque ligne représente un jour. Pour une table au format long, conserve aussi la clé de série, comme le capteur ou le magasin, afin que les opérations ultérieures puissent s’exécuter séparément par série.
Points clés
- Convertis les dates avant de définir l’index temporel, puis trie-le.
- Vérifie séparément l’ordre et l’unicité.
- Traite les étiquettes en double selon ce que représentent leurs lignes.
- Compare les données à un calendrier complet pour trouver les dates absentes.
2.2 Sélectionner les lignes selon la date et l’heure
Une fois que l’index contient des valeurs datetime triées, les chaînes de dates deviennent des sélecteurs utiles. Leur précision détermine la durée qu’elles représentent : une année, un mois, un jour ou une minute précise.
Sélectionner une période calendaire entière
Pour des données quotidiennes de janvier à mars 2025, ts.loc["2025"] sélectionne les 90 jours. ts.loc["2025-02"] sélectionne les 28 jours de février. Sur des données horaires, une chaîne représentant un jour sélectionne toute cette journée, pas seulement minuit.
Utilise aussi .loc sur un DataFrame :
february = df.loc["2025-02", "kwh"]
spring_onward = df.loc["2025-03-01":]
df["2025-02"] demande quant à lui une colonne portant ce nom. La présence d’un index temporel ne transforme pas la sélection de colonnes entre crochets en sélection de lignes.
Lire précisément la borne
Une tranche par étiquettes inclut les deux bornes. ts.loc["2025-01-30":"2025-02-02"] inclut les 30 et 31 janvier ainsi que les 1er et 2 février. Une tranche par positions comme ts.iloc[0:4] s’arrête avant la position 4.
La fin d’une tranche définie par une chaîne partielle inclut toute la période nommée. Sur des données horaires, df.loc[:"2025-06-01"] inclut tout le 1er juin. df.loc[:"2025-06-01 00:00"] s’arrête à minuit. De même, une tranche se terminant par « 2025-02 » inclut tout le mois de février. Choisir une chaîne plus précise modifie la borne : écris donc la limite en fonction de la question.
ts.truncate(before="2025-03-01") conserve les données à partir du 1er mars. Son argument after= coupe l’autre extrémité. Trier d’abord évite les erreurs qui peuvent survenir lorsque des tranches définies par des chaînes de dates rencontrent des étiquettes non ordonnées.
Sélectionner des conditions calendaires récurrentes
Les attributs calendaires produisent des masques booléens :
weekends = df[df.index.day_of_week >= 5]
evening_march = df[(df.index.month == 3) & (df.index.hour >= 18)]
Lundi vaut 0, donc samedi et dimanche valent 5 et 6. Chaque condition doit être entre parenthèses lorsqu’elles sont combinées avec & ou |. Avec une colonne datetime, utilise df["timestamp"].dt.day_of_week au lieu d’un attribut de l’index. Le masque des jours de la semaine sélectionne un motif calendaire répété ; il se distingue de la sélection d’un seul intervalle de dates continu.
Sélectionner une plage horaire à chaque date
df.between_time("09:00", "17:00") sélectionne ces heures chaque jour. Les deux bornes sont incluses par défaut, ce qui donne neuf lignes pour une journée complète de données horaires. inclusive="left" inclut 09 h et exclut 17 h, ce qui en donne huit. df.at_time("12:00") sélectionne exactement midi chaque jour.
Une plage horaire peut traverser minuit. between_time("22:00", "06:00") sélectionne les lignes de fin de soirée et de début de matinée dans tout l’index. Il ne sélectionne pas un intervalle continu entre deux dates précises. Sur un index avec fuseau horaire, la sélection par chaîne de dates utilise le fuseau local de l’index ; convertis l’index avant de sélectionner un jour de compte rendu dans un autre fuseau.
Points clés
- Une chaîne de date partielle sélectionne toute la période correspondante.
- Les tranches par étiquettes incluent la borne de fin ; les tranches par positions l’excluent.
- Utilise
.locpour sélectionner des dates dans un DataFrame. - Les masques calendaires et les plages horaires sélectionnent des motifs récurrents.
- Vérifie la précision de la borne et le fuseau horaire avant de filtrer.
2.3 Comparer les valeurs au fil du temps à l’aide de décalages, de différences et de variations en pourcentage
Une variation nécessite un point de comparaison clair. « Précédent » peut désigner la ligne observée précédente, le jour calendaire précédent ou le même mois un an auparavant. Choisis ce sens avant de calculer un retard ou un taux de croissance.
Placer les valeurs antérieures à côté des valeurs actuelles
Pour les nombres de visiteurs 200, 210 et 189 du 3 au 5 mars, s.shift(1) donne NaN, 200 et 210. Il déplace les valeurs d’une ligne vers le bas tout en conservant les étiquettes. La nouvelle première case est manquante car aucune observation antérieure n’existe. shift(-1) donne 210, 189 et NaN : c’est une avance qui place la valeur suivante sur la ligne actuelle.
df["previous"] = df["visitors"].shift(1)
df["change"] = df["visitors"].diff()
df["growth"] = df["visitors"].pct_change()
diff() soustrait la valeur précédente et donne NaN, 10 et −21. pct_change() divise la valeur actuelle par la précédente et soustrait 1, ce qui donne NaN, 0,05 et −0,10. Ce sont des fractions : 0,05 signifie 5 %, pas 0,05 %. Le résultat en virgule flottante peut comporter de petits chiffres supplémentaires ; arrondis pour l’affichage après le calcul.
Choisir le retard en lignes ou en temps
pct_change(7) compare avec la valeur située sept lignes auparavant. Cela correspond au même jour de la semaine précédente uniquement s’il y a exactement une ligne par jour sans lacune. Sur une série mensuelle complète, pct_change(12) donne la variation par rapport à l’année précédente.
shift(1, freq="D") avance les horodatages d’un jour et laisse les valeurs associées à ces étiquettes déplacées. Il conserve toutes les valeurs. Les calculs avec la série d’origine s’alignent ensuite par date :
previous_day = s.shift(1, freq="D")
daily_change = s - previous_day
Si la source contient des observations uniquement le lundi et le jeudi, un simple shift(1) compare le jeudi au lundi. Un décalage de date permet une comparaison avec le mercredi ; si le mercredi est absent, la variation quotidienne du jeudi est manquante. Combler cette lacune est une décision distincte concernant les données.
Prévoir l’alignement des étiquettes dans les calculs
Deux Series se combinent par horodatage et non par position des lignes. Additionne les valeurs 200, 210 et 189 des 3, 4 et 5 mars aux valeurs 1 et 1 des 4 et 7 mars. Seul le 4 mars possède deux observations, donc sa somme vaut 211. L’union des dates comprend les 3, 4, 5 et 7 mars ; les autres résultats sont manquants.
Utilise s.add(other, fill_value=0) lorsqu’une observation absente signifie réellement zéro, comme pour un nombre d’événements vérifié. Ce n’est pas une correction générale pour les relevés de capteurs manquants.
Recommencer les comparaisons pour chaque série
Trie une table au format long par clé de série et par date, puis calcule au sein des groupes. df.groupby("store")["sales"].pct_change() ne compare chaque magasin qu’à lui-même. Pour le magasin A qui vend pour 100 puis 110 et le magasin B qui vend pour 50 puis 40, les taux de croissance sont manquant, 0,10, manquant et −0,20. Un calcul simple sur toute la colonne comparerait la première vente de B à la dernière vente de A. Ce résultat numérique décrirait un changement de magasin, pas une croissance au fil du temps.
Points clés
- Un retard place les valeurs antérieures à côté des valeurs ultérieures.
pct_change()renvoie une fraction ; multiplie-la par 100 pour l’exprimer en pourcentage.- Les décalages de lignes et les décalages de dates répondent à des questions différentes.
- Les calculs alignent les horodatages, pas les positions.
- Calcule les variations séparément dans chaque série.
3Générer des dates et utiliser les fréquences, les décalages et les périodes
Les règles calendaires rendent fiables les opérations répétées sur les dates. Génère une séquence complète à partir d’une fréquence, passe à la fin de mois ou au jour ouvré suivant et utilise des périodes pour désigner des mois ou des trimestres entiers. Chaque représentation répond à une question différente : une durée compte le temps écoulé, un décalage suit une règle calendaire et une période désigne un intervalle. Lire attentivement les points d’ancrage et les bornes évite les erreurs d’une unité et les confusions entre exercices.
3.1 Créer des séquences régulières de dates avec des alias de fréquence
Une séquence régulière de dates est un calendrier que tu peux générer au lieu de saisir chaque étiquette. Elle peut servir à étiqueter des données de test, à définir une grille de compte rendu attendue ou à révéler des observations manquantes après réindexation.
Indiquer un début et une règle
ends = pd.date_range("2025-01-01", periods=4, freq="ME")
Les quatre horodatages correspondent aux 31 janvier, 28 février, 31 mars et 30 avril. « ME » signifie fin de mois : la première date est donc la première fin de mois égale ou postérieure au début. Une fréquence régulière peut suivre une règle calendaire même lorsque les durées écoulées entre les dates varient.
Indique normalement deux des arguments start, end et periods, ainsi que freq. Sans fréquence explicite, la valeur par défaut est un jour calendaire. periods est un nombre d’horodatages, pas un nombre d’intervalles : quatre horodatages horaires contiennent trois intervalles.
Lire les alias courants
| Règle | Alias | Exemple d’utilisation |
|---|---|---|
| Jour calendaire ou ouvré | D, B | Dates quotidiennes ou du lundi au vendredi |
| Semaine ancrée sur un jour | W, W-MON | Dimanches ou lundis |
| Borne de mois | MS, ME | Premier ou dernier jour calendaire |
| Borne de trimestre | QS, QE | Début ou fin de trimestre |
| Borne d’année | YS, YE | Début ou fin d’année |
| Intervalle horaire fixe | h, min, s, ms | De l’heure à la milliseconde |
Les multiples expriment des intervalles plus larges : « 15min », « 2h » et « 90min ». En commençant à 08 h avec quatre périodes de « 90min », on obtient 08 h, 09 h 30, 11 h et 12 h 30. « 1h30min » exprime le même espacement.
Les fréquences d’horodatages de pandas 3 utilisent « ME », « QE », « YE », « BME », « h », « min », « s », « ms » et « us ». Les anciens alias « M », « Q », « Y » ou « A », « BM », « H », « T », « S », « L » et « U » ne fonctionnent plus dans ces opérations sur les horodatages. Les périodes mensuelles utilisent toujours « M », car une période décrit un intervalle.
Suivre les points d’ancrage et les jours ouvrés
Une séquence ancrée n’inclut pas nécessairement la date de début fournie dans son résultat. En commençant le 15 janvier 2025 avec freq="MS", on obtient d’abord le 1er février. En janvier 2025, « W-MON » donne les 6, 13, 20 et 27 janvier ; « W » seul donne les dimanches. « WOM-3FRI » désigne le troisième vendredi de chaque mois.
« B » ignore les week-ends, mais ne connaît pas les jours fériés locaux. Mars 2025 contient 21 dates du lundi au vendredi. Un calendrier personnalisé peut exclure un jour férié indiqué :
pd.bdate_range("2025-03-01", "2025-03-31",
freq="C", holidays=["2025-03-17"])
Cette séquence contient 20 dates. La liste des jours fériés est explicite ; aucun pays n’est inféré à partir du fuseau horaire ou de la langue.
Compter soigneusement les bornes
Les bornes de début et de fin qui correspondent à la fréquence sont incluses par défaut. Une séquence horaire allant du 1er janvier à minuit au 2 janvier à minuit donne 25 horodatages. Utilise periods=24 pour obtenir exactement 24 relevés horaires, ou inclusive="left" pour exclure la fin. normalize=True ramène les heures de début et de fin à minuit. Ajoute tz="Asia/Tokyo" lorsque les étiquettes générées doivent porter un fuseau.
Points clés
- Les alias de fréquence expriment des intervalles horaires ou des points d’ancrage calendaires.
- Une séquence ancrée commence à la première date qui correspond à la règle.
- Les séquences de jours ouvrés nécessitent une indication explicite des jours fériés.
- Compte séparément les horodatages et l’inclusion des bornes.
- Utilise les alias actuels de pandas 3 pour les fréquences d’horodatages.
3.2 Décaler des dates selon les règles du calendrier
« Un mois plus tard » est une instruction calendaire. « Trente jours plus tard » désigne un temps écoulé. Les résultats peuvent différer, car les mois et les années ne contiennent pas tous le même nombre de jours.
Distinguer durée et déplacement calendaire
Un Timedelta ajoute une durée écoulée fixe. Un DateOffset suit les composantes du calendrier. À partir du 31 janvier 2025 :
t = pd.Timestamp("2025-01-31")
t + pd.DateOffset(months=1) # February 28
t + pd.Timedelta(days=30) # March 2
Pour le DateOffset, on passe d’abord à février, puis on conserve le jour 31 s’il existe. Ce n’est pas le cas : pandas ramène donc la date au dernier jour valide de février. À partir du 31 janvier 2024, le résultat est le 29 février, car c’est une année bissextile. pd.Timedelta(months=1) n’est pas valide : un mois n’a pas une durée fixe unique.
La même distinction s’applique aux années. À partir du 1er janvier 2024, 365 jours écoulés aboutissent au 31 décembre 2024. pd.DateOffset(years=1) aboutit au 1er janvier 2025. Utilise l’unité désignée par la question posée au lieu de lui substituer un nombre de jours commode.
Passer à un point d’ancrage calendaire
pd.offsets.MonthEnd(1) passe à la fin de mois suivante. En partant du 15 janvier 2025, on obtient le 31 janvier. En partant du 31 janvier, on obtient le 28 février. Le nombre un signifie qu’on avance jusqu’à un point d’ancrage : une date qui correspond déjà à la règle est donc également déplacée.
MonthEnd(0) avance une date jusqu’à la fin de son mois, mais laisse inchangée une date déjà en fin de mois. Cela permet d’étiqueter chaque observation avec la fin de son mois :
month_labels = df.index + pd.offsets.MonthEnd(0)
Un décalage possède aussi rollforward() et rollback(). Pour le 15 janvier, le point d’ancrage MonthEnd le plus proche vers l’avant est le 31 janvier et le plus proche vers l’arrière est le 31 décembre 2024. Ces opérations sélectionnent le point d’ancrage valide le plus proche dans une direction donnée.
Avancer en jours ouvrés
Le 14 mars 2025 est un vendredi. Ajouter pd.offsets.BDay(1) donne le lundi 17 mars. Ajouter un jour écoulé donne le samedi 15 mars. Une règle standard de jours ouvrés ignore les week-ends ; pour les jours fériés, il faut fournir explicitement un calendrier personnalisé.
Les chaînes de fréquence sont des noms courts pour les objets de décalage : « ME » correspond à MonthEnd, « B » à BusinessDay et « W-MON » à une semaine ancrée sur le lundi. Cela permet d’appliquer la même règle calendaire à une séquence, à une règle de rééchantillonnage ou à un décalage de date.
Conserver l’heure voulue lors du changement d’heure
Dans pandas 3, pd.offsets.Day(1) désigne un jour calendaire et conserve l’heure locale affichée. pd.Timedelta(days=1) ajoute exactement 24 heures. À partir du 29 mars 2025 à midi à Amsterdam, le décalage calendaire aboutit au 30 mars à midi, après seulement 23 heures écoulées. Le Timedelta aboutit à 13 h. Un rendez-vous local récurrent et une durée de fonctionnement mesurée d’un équipement nécessitent donc des opérations différentes.
Points clés
- Les mois et les années suivent des règles calendaires ; ce ne sont pas des durées fixes.
- Un décalage d’un mois ramène la date au dernier jour valide du mois cible si nécessaire.
MonthEnd(1)avance une date déjà en fin de mois ;MonthEnd(0)la conserve.- Les décalages en jours ouvrés ignorent les week-ends.
- Un jour calendaire et 24 heures écoulées peuvent différer.
3.3 Représenter des mois, des trimestres et des exercices entiers par des périodes
Un total de ventes mensuel appartient à un mois entier. Il est possible de l’étiqueter avec un seul horodatage, mais un Period indique directement l’intervalle correspondant. Une période combine une valeur et une fréquence : « 2025-03 » avec la fréquence « M » désigne donc tout le mois de mars 2025.
Représenter et déplacer des périodes
march = pd.Period("2025-03", freq="M")
months = pd.period_range("2025-01", "2025-04", freq="M")
months est un PeriodIndex de quatre éléments de type period[M]. Le start_time de mars est le 1er mars à minuit ; son end_time est le 31 mars à 23:59:59.999999 avec une résolution à la microseconde. La fin est le dernier instant, pas minuit au début du dernier jour.
Les calculs sur les périodes se font dans l’unité propre à leur fréquence. march + 1 donne avril 2025. Juin moins mars à la fréquence mensuelle donne un décalage de trois fins de mois, dont .n vaut 3. Une période mensuelle connaît aussi .days_in_month : février 2025 compte 28 jours.
Convertir des instants en périodes et inversement
monthly_labels = df.index.to_period("M")
column_labels = df["date"].dt.to_period("M")
start_labels = monthly_labels.to_timestamp()
end_labels = monthly_labels.to_timestamp(how="end")
Chaque horodatage de mars correspond à la même période mensuelle. La conversion inverse de cette période donne son début par défaut ou sa fin sur demande. Elle ne retrouve pas le jour et l’heure d’origine d’une observation : la conversion en période a supprimé ce détail.
Distingue les familles d’alias. Une période mensuelle utilise « M » dans Period et period_range. Un horodatage de fin de mois utilise « ME » dans date_range et le rééchantillonnage datetime. Les deux noms décrivent des types d’étiquettes différents.
Modifier la fréquence d’une période
La méthode .asfreq() d’une période sélectionne une période englobante ou incluse à une fréquence différente. march.asfreq("D", how="start") donne le 1er mars comme période quotidienne ; how="end" donne le 31 mars. Une période annuelle convertie en « M » avec how="start" donne janvier.
Cette opération sélectionne une période à la borne ; elle ne répartit pas un total mensuel entre les jours. Pour une série avec PeriodIndex, le rééchantillonnage peut agréger des périodes mensuelles en périodes trimestrielles. Les nombres de jours de chaque mois de 2025 donnent par addition les totaux trimestriels 90, 91, 92 et 92.
Lire les étiquettes des trimestres d’exercice
Un trimestre d’exercice est nommé au sein d’un exercice dont le mois de clôture est explicite. Avec « Q-JUN », l’exercice 2025 se termine en juin 2025. Son premier trimestre va donc de juillet à septembre 2024 :
q = pd.Period("2025Q1", freq="Q-JUN")
Avec « Q-MAR », le 10 mai 2025 appartient à 2026Q1, car cet exercice se termine en mars 2026. L’année d’une étiquette d’exercice ne correspond pas nécessairement à l’année civile de son premier jour. Pour filtrer des horodatages, sélectionner les instants antérieurs au début de la période suivante est souvent plus clair que construire la dernière fraction de seconde de la période actuelle.
Points clés
- Les périodes décrivent des intervalles et se déplacent dans l’unité de leur propre fréquence.
- La conversion en période supprime les détails plus précis de l’horodatage.
- Les alias de fréquence des périodes et des horodatages diffèrent.
- Les exercices sont désignés par leur année de clôture.
4Modifier la fréquence d’une série chronologique par rééchantillonnage
Modifier la fréquence change la question posée aux observations. Des relevés détaillés peuvent devenir des totaux quotidiens ou des moyennes mensuelles ; une série peu fournie peut devenir une grille plus fine comportant des créneaux vides. Choisis les agrégations et les méthodes de remplacement selon le sens des valeurs, puis vérifie les bornes des intervalles temporels. Lorsqu’une table contient plusieurs magasins ou capteurs, conserve leur identité dans le regroupement afin que leurs historiques restent distincts.
4.1 Sous-échantillonner pour calculer des totaux, des valeurs typiques et d’autres indicateurs
Le rééchantillonnage répond à des questions comme « Quelle quantité d’énergie a été consommée chaque jour ? » ou « Quelle était la température moyenne chaque mois ? ». Il répartit les observations dans des intervalles temporels, puis applique une agrégation.
Choisir une statistique adaptée à la grandeur
daily = df.resample("D").agg({"kwh": "sum", "temp_c": "mean"})
L’énergie en kWh et les précipitations en mm s’additionnent dans le temps. La température est un niveau : une moyenne la décrit donc plus utilement qu’une somme. last() convient à un solde de clôture, tandis que max() trouve un maximum. Les ventes quotidiennes peuvent être additionnées pour obtenir le total mensuel ou moyennées pour obtenir les ventes moyennes par jour observé ; c’est la question qui détermine le choix.
resample() renvoie un Resampler jusqu’à l’appel d’une agrégation comme sum(), mean(), count() ou agg(). Utilise on="date" lorsque les valeurs datetime sont dans une colonne plutôt que dans l’index.
Lire les intervalles calendaires et les couvertures partielles
Une série quotidienne de valeurs égales à un du 1er janvier au 30 avril 2025 donne les totaux mensuels 31, 28, 31 et 30 avec resample("ME").sum(). « MS » donne les mêmes totaux mensuels avec des étiquettes de début de mois. Le rééchantillonnage en fins de trimestre donne 90 pour janvier à mars et 30 pour un deuxième trimestre ne contenant qu’avril. Une étiquette au 30 juin ne prouve pas que mai et juin ont été observés.
Les intervalles hebdomadaires « W » se terminent le dimanche. Les valeurs quotidiennes de 1 à 14 à partir du lundi 3 mars donnent une somme de 28 pour la semaine étiquetée 9 mars et de 77 pour celle étiquetée 16 mars. « W-MON » se termine le lundi ; le premier intervalle ne contient alors que le 3 mars. Vérifie le jour d’ancrage avant de considérer une étiquette comme le début d’une semaine.
Distinguer l’appartenance de l’étiquetage
closed détermine quelle borne appartient à un intervalle. label détermine l’horodatage affiché sur le résultat. Pour la plupart des règles, dont « 5min », « h », « D » et « MS », les deux valent « left » par défaut.
Les valeurs de 0 à 9, à raison d’une par minute à partir de 00 h, produisent par défaut deux sommes sur cinq minutes : 10 étiqueté 00 h et 35 étiqueté 00 h 05. Le premier intervalle contient les valeurs de 00 h à 00 h 04. Avec closed="right", label="right", les résultats sont 0 à 00 h, 15 à 00 h 05 et 30 à 00 h 10. L’intervalle central contient les valeurs de 00 h 01 à 00 h 05. Modifier uniquement l’étiquette ne changerait pas l’appartenance des observations.
Les règles de fin comme « ME », « QE », « YE », « W » et « BME » sont par défaut fermées à droite et étiquetées à droite. Les intervalles de durée fixe sont normalement alignés à partir de minuit le premier jour : les bornes de 15 minutes sont donc 00 h, 00 h 15, et ainsi de suite.
Distinguer les intervalles vides des vrais zéros
Pour un jour vide, sum() vaut 0, count() vaut 0 et mean() vaut NaN. Utilise sum(min_count=1) pour conserver une valeur manquante lorsqu’aucun relevé n’est disponible. Un zéro enregistré et un relevé absent restent alors distincts.
Pour obtenir plusieurs indicateurs d’une série, .ohlc() donne ouverture, plus haut, plus bas et clôture : la première valeur observée, le maximum, le minimum et la dernière valeur observée dans chaque intervalle. Les relevés 10, 12 et 11 donnent une ouverture à 10, un plus haut à 12, un plus bas à 10 et une clôture à 11. L’ouverture et la clôture dépendent de l’ordre temporel, pas de la grandeur numérique.
Points clés
- Choisis les agrégations selon le sens des valeurs.
closeddétermine l’appartenance ;labeldétermine l’heure affichée.- Les étiquettes hebdomadaires désignent normalement le dernier jour de la semaine.
- Vérifie si les premier et dernier intervalles sont incomplets.
sum(min_count=1)conserve les intervalles vides comme valeurs manquantes.- OHLC désigne la première valeur, le maximum, le minimum et la dernière valeur.
4.2 Suréchantillonner et combler les lacunes d’une série chronologique
Une grille plus fine crée des créneaux, pas des mesures. Avant de les remplir, détermine si chaque valeur représente un état, un effectif, une mesure qui évolue progressivement ou un total sur une période.
Faire apparaître les nouveaux créneaux
s = pd.Series([10.0, 16.0],
index=pd.to_datetime(["2025-06-01", "2025-06-04"]))
daily = s.asfreq("D")
Le résultat quotidien est 10, NaN, NaN, 16. s.resample("D").asfreq() donne ici la même grille. Les valeurs sont conservées aux horodatages correspondants ; les nouvelles dates ne contiennent aucune observation d’origine.
Remplacer selon le sens des valeurs
| Méthode | Résultat du 1er au 4 juin | Sens adapté |
|---|---|---|
ffill() | 10, 10, 10, 16 | Un état reste valable jusqu’à sa modification |
bfill() | 10, 16, 16, 16 | Une valeur ultérieure est utilisée pour les créneaux précédents |
interpolate() | 10, 12, 14, 16 | La transition est estimée le long d’une droite |
Un réglage de thermostat reste valable jusqu’à ce que quelqu’un le modifie : la propagation de la dernière valeur connue est donc utile. Un niveau d’eau qui évolue progressivement peut justifier une interpolation. Zéro ne convient à un nombre d’événements que si l’enregistrement manquant signifie qu’il n’y a eu aucun événement. Une panne de capteur ne prouve pas que la mesure vaut zéro.
L’exemple d’interpolation utilise une grille quotidienne régulière. La variation totale est de 6 sur trois pas d’un jour : chaque pas ajoute donc 2. Les deux valeurs intermédiaires sont des estimations, pas des mesures retrouvées.
La propagation de la prochaine valeur connue utilise des informations futures. Elle ne peut pas décrire ce qu’un observateur savait à chaque instant antérieur. La propagation de la dernière valeur connue respecte ce sens du temps, mais de longues lacunes peuvent tout de même rendre l’état propagé périmé. daily.ffill(limit=1) remplit un créneau après un relevé, ce qui donne 10, 10, NaN, 16 dans cet exemple.
Utiliser des bornes explicites pour le compte rendu
asfreq("D") couvre la période allant du premier au dernier horodatage de la source. Réindexe lorsque le calendrier doit s’étendre davantage :
calendar = pd.date_range("2025-06-01", "2025-06-05", freq="D")
complete = s.reindex(calendar)
Le 5 juin est maintenant visible lui aussi. Lors de la réindexation, fill_value=0 remplit les étiquettes nouvellement créées, ce qui est utile pour les jours vérifiés sans événement. Il ne remplace pas les valeurs manquantes déjà présentes dans la source. La réindexation et asfreq() nécessitent toutes deux des étiquettes sources uniques.
Distinguer échantillonnage et agrégation
asfreq() sélectionne les valeurs aux horodatages cibles. Il ne calcule pas d’indicateur sur les observations situées entre eux. Sur 48 valeurs horaires numérotées de 0 à 47, asfreq("D") sélectionne les relevés de minuit 0 et 24. resample("D").sum() donne quant à lui 276 et 852 en additionnant toutes les valeurs horaires de chaque jour.
Un total mensuel ne peut pas être propagé sur chaque jour puis additionné : cela compterait le même total plusieurs fois. Une répartition quotidienne égale nécessite de diviser par le nombre de jours du mois. C’est une hypothèse de répartition, distincte de la propagation d’un état ou de l’estimation d’une mesure qui évolue progressivement.
Points clés
- Une grille plus fine ajoute des créneaux vides, pas des observations.
- Choisis le remplacement selon le sens de la grandeur et le sens du temps.
- Limite le remplacement lorsque les longues lacunes doivent rester visibles.
asfreq()sélectionne des points ; le rééchantillonnage avec agrégation calcule des indicateurs par intervalle.
4.3 Rééchantillonner plusieurs séries à la fois par groupe
Une table au format long peut contenir de nombreuses séries dans une seule colonne de valeurs. Une clé de magasin distingue les magasins et une clé de capteur distingue les capteurs. Regroupe selon cette identité ainsi que selon le temps lorsque la question demande un historique distinct pour chaque série.
Combiner une clé de série et une règle temporelle
monthly = df.groupby([
"store", pd.Grouper(key="date", freq="ME")
])["sales"].sum()
pd.Grouper place une règle d’intervalles temporels dans groupby. key= désigne une colonne datetime ; level= peut désigner un niveau d’index datetime. Le résultat possède un niveau d’index pour le magasin et un autre pour la fin de mois. La sélection de la colonne de nombres limite l’agrégation aux ventes.
Supposons que le magasin A vende pour 100 le 5 janvier, 150 le 20 janvier et 120 le 3 février. Le magasin B vend pour 80 le 11 janvier, 90 le 14 février et 60 le 25 février. Le résultat regroupé est A : janvier 250, février 120 ; B : janvier 80, février 150. Rééchantillonner toute la table sans la clé de magasin combinerait les magasins et donnerait 330 en janvier et 270 en février.
Rééchantillonner au sein de chaque groupe
Une seconde forme définit d’abord la date comme index :
monthly = (df.set_index("date")
.groupby("store")["sales"]
.resample("ME").sum())
Elle produit les mêmes totaux pour les combinaisons magasin-mois observées. Les deux formes diffèrent lorsqu’un magasin n’a aucune ligne pendant un mois intermédiaire. Si A n’apparaît qu’en janvier et en mars, le rééchantillonnage par groupe crée un intervalle pour février entre la première et la dernière date de A ; un sum() ordinaire y donne zéro. Le regroupement par magasin et par Grouper conserve les combinaisons qui contiennent des lignes : la combinaison de A pour février est donc absente.
Une combinaison absente, un intervalle vide dont l’agrégation donne zéro et une mesure manquante sont des états de données différents. Détermine lequel le compte rendu doit montrer. Utilise une réindexation explicite lorsque tous les magasins doivent partager un calendrier plus large que leur plage observée. Utilise min_count=1 avec une somme lorsqu’un intervalle vide doit rester manquant.
Remodeler pour comparer
monthly.unstack("store") déplace le niveau des magasins dans les colonnes et laisse les mois en lignes. Dans l’exemple, janvier donne A = 250 et B = 80 ; février donne A = 120 et B = 150. Une combinaison magasin-mois manquante devient NaN ; unstack("store", fill_value=0) remplace les combinaisons manquantes par zéro lorsque ce sens convient.
Garder les années distinctes si nécessaire
Un objet Grouper temporel avec « ME » garde janvier 2024 et janvier 2025 distincts. Le regroupement avec df["date"].dt.month ne conserve que les numéros de mois et fusionne les deux mois de janvier. La première forme répond à « Que s’est-il passé chaque mois ? ». La seconde permet une comparaison saisonnière comme les ventes moyennes de janvier sur plusieurs années. Le choix dépend de l’identité temporelle à conserver.
Points clés
- Regroupe selon l’identité de la série et le temps pour conserver des historiques distincts.
- Le rééchantillonnage par groupe et un objet Grouper temporel traitent différemment les mois vides.
unstack()facilite la comparaison des séries en colonnes.- Les numéros de mois réunissent les années ; les intervalles temporels mensuels les gardent distinctes.
5Lisser les données et calculer des indicateurs avec des fenêtres glissantes et croissantes
Les statistiques de fenêtre décrivent l’évolution d’une série sans la réduire à un seul nombre global. Un calcul glissant suit les lignes récentes ou le temps récemment écoulé, un calcul croissant conserve l’historique et une moyenne à pondération exponentielle privilégie progressivement les observations les plus récentes. Examine quelles valeurs entrent dans chaque résultat, comment les données manquantes l’affectent et où il est étiqueté. Ces choix déterminent ce qu’une valeur lissée peut t’apprendre.
5.1 Calculer des statistiques glissantes sur un nombre fixe de lignes
Une fenêtre glissante calcule à plusieurs reprises un indicateur sur un groupe de lignes qui se déplace. À chaque nouvelle ligne, la fenêtre gagne la valeur actuelle et finit par perdre sa valeur la plus ancienne. La longueur de la fenêtre détermine dans quelle mesure les fluctuations à court terme sont lissées.
Examiner une fenêtre à la fois
Pour les valeurs 4, 8, 6, 10 et 12 :
s = pd.Series([4, 8, 6, 10, 12])
s.rolling(3).mean()
La première fenêtre complète est [4, 8, 6], de somme 18 et de moyenne 6. La suivante est [8, 6, 10], de moyenne 8. La dernière est [6, 10, 12], de moyenne environ 9,333. Les résultats par défaut sont NaN, NaN, 6, 8 et 9,333, car les deux premières lignes ne disposent pas encore de trois observations.
Maîtriser les exigences de données et le placement
min_periods définit le nombre requis de valeurs non manquantes. Pour une fenêtre définie par un nombre de lignes, sa valeur par défaut est la taille complète de la fenêtre. Avec min_periods=1, les premières moyennes utilisent une valeur puis deux : 4 et 6. Leurs échantillons plus petits les rendent moins stables que les moyennes ultérieures calculées sur trois valeurs.
Les valeurs manquantes occupent toujours des positions de lignes. Dans [4, NaN, 6, 10, 12], une fenêtre de trois lignes contenant la valeur manquante ne possède que deux observations valides. min_periods=2 permet de calculer la moyenne de [4, NaN, 6], qui vaut 5 ; la valeur par défaut ne le permet pas.
Les résultats appartiennent normalement à la dernière ligne de la fenêtre. Avec center=True, les trois mêmes moyennes de fenêtres complètes apparaissent sur les lignes centrales, ce qui donne NaN, 6, 8, 9,333, NaN. Une valeur centrée utilise des observations ultérieures par rapport à son étiquette. Utilise des fenêtres rétrospectives pour décrire ce qui était connu à chaque instant.
Calculer d’autres indicateurs que la moyenne
Les mêmes fenêtres permettent d’utiliser sum(), max(), min() et std(). pandas utilise par défaut l’écart-type d’échantillon : [4, 8, 6] a un écart-type de 2. Une fonction personnalisée peut calculer une étendue :
s.rolling(3).apply(lambda v: v.max() - v.min(), raw=True)
Les étendues des fenêtres complètes sont 4, 4 et 6. raw=True transmet les valeurs du tableau à la fonction. Deux séries alignées peuvent aussi partager une fenêtre : a.rolling(3).corr(b) mesure la corrélation sur les trois dernières observations appariées, de sorte que la liaison peut évoluer au fil du temps.
Choisir une longueur et un regroupement qui ont un sens
Avec une ligne quotidienne complète par jour, une moyenne sur sept lignes contient une fois chaque jour de la semaine et élimine par moyennage une composante fixe qui se répète chaque semaine. Une moyenne sur douze lignes fait de même pour une composante annuelle fixe dans des données mensuelles complètes. Les fenêtres plus longues lissent davantage mais réagissent plus tard aux changements de direction ; une moyenne rétrospective sur n lignes accuse un retard d’environ une demi-fenêtre, soit environ (n − 1) / 2 lignes.
Les lignes ne sont pas des jours. Sept relevés avec des lacunes peuvent couvrir plus d’une semaine. Utilise une fenêtre temporelle lorsque la question porte sur le temps écoulé. Dans une table au format long, trie chaque série dans l’ordre chronologique et applique les fenêtres au sein de son groupe : df.groupby("store")["sales"].rolling(2).sum(). Cela empêche une fenêtre de passer des données d’un magasin à celles d’un autre.
Points clés
- Une fenêtre définie par un nombre de lignes compte les lignes, y compris les positions contenant des valeurs manquantes.
min_periodscompte les observations valides.- Les fenêtres centrées incluent des valeurs ultérieures par rapport à leurs étiquettes.
- Les fenêtres plus longues lissent davantage et réagissent plus lentement.
- Applique les fenêtres séparément au sein de chaque série.
- Les méthodes glissantes peuvent décrire la dispersion et les liaisons ainsi que les niveaux.
5.2 Utiliser des fenêtres temporelles pour des données irrégulières
Les événements irréguliers demandent des fenêtres définies par le temps. « Les commandes des trois derniers jours » doit conserver la même durée, même lorsqu’il y a beaucoup de commandes un jour et aucune le lendemain.
Définir une fenêtre de temps écoulé
s = pd.Series([5, 3, 4, 6], index=pd.to_datetime([
"2025-05-01", "2025-05-02", "2025-05-05", "2025-05-06"
]))
s.rolling("3D").sum()
Les résultats sont 5, 8, 4 et 10. Contrairement à rolling(3), la chaîne « 3D » définit une durée de trois jours. Le nombre de lignes dans cette durée peut varier. Trie d’abord le DatetimeIndex ; les fenêtres temporelles nécessitent des instants monotones. Un DataFrame peut utiliser une colonne datetime triée avec on="date".
Vérifier la borne avant d’additionner
Par défaut, la fenêtre inclut l’instant actuel et exclut l’instant situé exactement trois jours auparavant. Le 5 mai à minuit, l’intervalle va de juste après le 2 mai à minuit jusqu’au 5 mai à minuit inclus. Le relevé du 2 mai se trouve exactement sur la borne exclue : seule la valeur 4 du 5 mai contribue donc à la somme.
Le 6 mai, la fenêtre commence juste après le 3 mai et inclut les valeurs 4 et 6, de somme 10. Avec closed="both", la fenêtre du 5 mai inclut aussi le 2 mai et sa somme vaut 7. Le choix d’une borne peut modifier un résultat même lorsque les données et la durée restent identiques.
Une fenêtre de deux lignes sur cette série donne NaN, 8, 7 et 10. Au 5 mai, elle inclut la ligne précédente du 2 mai. Cela répond à la question « les deux derniers relevés », qui diffère de « les trois derniers jours ».
Définir le nombre d’observations requis
Le min_periods d’une fenêtre temporelle vaut 1 par défaut. La première observation peut donc produire immédiatement un résultat. s.rolling("3D").count() donne 1, 2, 1 et 2 relevés, ce qui montre que le nombre d’observations sur lequel repose le résultat change. Une moyenne fondée sur un relevé et une moyenne fondée sur de nombreux relevés sont toutes deux des calculs valides, mais ne reposent pas sur la même quantité de données.
Avec min_periods=2, les sommes sont NaN, 8, NaN, 10. La durée n’a pas changé ; le calcul exige maintenant au moins deux observations non manquantes pendant cette durée. Un intervalle temporel plus large ne garantit pas à lui seul davantage d’observations.
Utiliser des durées fixes et séparer les séries
Une fenêtre glissante temporelle nécessite une durée fixe comme « 30min », « 24h » ou « 7D ». Une règle de fin de mois comme « 1ME » a une durée variable et ne peut pas définir ce type de fenêtre. Utilise une durée fixe explicite comme « 30D » si c’est la règle voulue, ou agrège d’abord dans des intervalles mensuels si la question porte sur des mois calendaires.
Pour obtenir des historiques distincts par client, df.groupby("customer").rolling("30D", on="date")["amount"].sum() garde ensemble les transactions de chaque client. Les instants doivent être ordonnés au sein de chaque client. Le résultat ajoute la clé de groupe comme niveau d’index, ce qui conserve l’identité de la série décrite par chaque fenêtre.
Points clés
- Les fenêtres temporelles sélectionnent selon une durée et peuvent contenir des nombres de lignes différents.
- Par défaut, la borne gauche est exclue et l’instant actuel est inclus.
- Le
min_periodsd’une fenêtre temporelle vaut 1 par défaut. - Les mois calendaires ne peuvent pas servir de durées fixes pour les fenêtres glissantes.
5.3 Suivre les sommes cumulées, les maximums cumulés et les moyennes à pondération exponentielle
Certaines questions nécessitent tout l’historique : « Quel total a été accumulé ? » ou « Quelle est la valeur la plus élevée jusqu’ici ? ». D’autres doivent privilégier les observations récentes sans écarter brutalement le passé. Les calculs croissants et à pondération exponentielle répondent à ces objectifs différents.
Agrandir l’historique d’une ligne à la fois
Pour les valeurs 4, 8, 6, 10 et 12, s.expanding().mean() donne 4, 6, 6, 7 et 8. Le quatrième résultat utilise les quatre valeurs : leur somme est de 28 et leur moyenne de 7. expanding().sum() donne 4, 12, 18, 28 et 40, comme cumsum() sur cette série complète. expanding().max() donne 4, 8, 8, 10 et 12, comme cummax().
Les fenêtres croissantes exigent par défaut une observation. Elles conservent toutes les observations antérieures avec le même poids. Vers la fin d’une longue série, une nouvelle valeur ne représente qu’une petite partie de tout cet historique : une moyenne cumulée réagit donc lentement.
Les totaux cumulés peuvent repartir à zéro à une borne :
ytd = df.groupby(df.index.year)["sales"].cumsum()
by_store = df.groupby("store")["sales"].cumsum()
Trie les données au sein de l’historique concerné avant de les cumuler. Une simple somme cumulée sur des magasins dont les lignes sont entrelacées les mélange.
Mesurer l’écart sous un maximum cumulé
Pour 100, 120, 90, 110 et 130, cummax() donne 100, 120, 120, 120 et 130. Calcule le drawdown avec s / s.cummax() - 1. Pour 90, la référence est le maximum précédent de 120 : le drawdown est donc de −0,25, soit 25 % sous le maximum. Comparer 90 à la première valeur de 100 répondrait à une autre question. Un nouveau maximum a un drawdown nul.
Donner plus de poids aux valeurs récentes
Une moyenne mobile à pondération exponentielle réduit le poids des valeurs anciennes selon un facteur constant. Le coefficient de lissage suit : span=3 donne donc 0,5. Pour adjust=False, la mise à jour est :
Ici, est la nouvelle observation, la valeur lissée précédente et le résultat mis à jour. La première valeur lissée est égale à la première observation. Ensuite, chaque nouvelle valeur reçoit un poids de 0,5 et la valeur lissée précédente reçoit un poids de 0,5 :
s.ewm(span=3, adjust=False).mean()
Pour 4, 8, 6, 10 et 12, les résultats sont 4, 6, 6, 8 et 10. La dernière mise à jour calcule la moyenne de la nouvelle observation 12 et de la valeur lissée précédente 8. Elle ne calcule pas la moyenne des deux seules observations brutes les plus récentes.
Comprendre le réglage de correction
La valeur par défaut adjust=True normalise par la somme des poids disponibles. Pour les mêmes données, les premiers résultats sont 4, environ 6,667, 6,286, 8,267 et 10,194. Ce calcul initial diffère de la forme récursive ; la différence s’atténue à mesure que l’historique s’allonge.
Choisis un argument de décroissance : span, alpha, com ou halflife. Une moyenne mobile à pondération exponentielle n’a pas de seuil net où une ancienne ligne disparaît soudainement. Une moyenne glissante possède ce seuil, tandis qu’une moyenne croissante conserve toutes les valeurs antérieures avec le même poids. Choisis selon l’influence à accorder aux changements récents.
Points clés
- Les fenêtres croissantes utilisent tout l’historique jusqu’à chaque ligne.
- Regroupe les calculs cumulés lorsque les historiques doivent repartir à zéro.
- Le drawdown compare une valeur à son maximum cumulé.
- Les poids d’une moyenne mobile à pondération exponentielle diminuent progressivement avec l’ancienneté.
adjust=Falseutilise la valeur lissée précédente dans sa mise à jour récursive.- La correction par défaut modifie les premières moyennes pondérées.
6Gérer les fuseaux horaires et l’heure d’été
Une heure locale affichée ne détermine un instant que lorsque son fuseau horaire est connu. Associe le fuseau d’enregistrement, convertis les instants réels entre fuseaux et garde les calculs alignés en UTC. Les comptes rendus locaux nécessitent ensuite les bonnes bornes calendaires, y compris les heures sautées ou répétées lors des changements d’heure. Distinguer localisation et conversion permet de combiner des enregistrements provenant de plusieurs lieux sans en décaler silencieusement le sens.
6.1 Localiser les horodatages et les convertir entre fuseaux horaires
Une heure affichée nécessite un lieu pour déterminer un instant. « 2025-07-01 09:00 » est un horodatage sans fuseau horaire. Lui ajouter « Europe/Amsterdam » le dote d’un fuseau horaire : en juillet, son décalage est de +02:00 et il représente 07 h UTC. UTC est la référence horaire commune et ne connaît pas de changement d’heure saisonnier.
Associer le fuseau d’enregistrement
local = pd.Timestamp("2025-07-01 09:00")
aware = local.tz_localize("Europe/Amsterdam")
tz_localize() conserve 09 h et lui associe le sens du fuseau. Utilise le lieu où l’heure affichée a été enregistrée. Considérer cette même heure comme UTC désignerait un instant différent, situé deux heures plus tard dans cet exemple.
Utilise des noms IANA comme « Europe/Amsterdam », « America/New_York » et « Asia/Kolkata ». Les fuseaux régionaux nommés conservent l’historique des décalages et les règles d’heure d’été. Un décalage fixe de +01:00 ne le fait pas. Les noms courts sont incohérents : « EST » est fixé à −05:00, tandis que « CET » suit les changements saisonniers. pandas 3 utilise la représentation zoneinfo de Python.
Convertir un instant déjà déterminé
aware.tz_convert("UTC") donne 07 h UTC. Convertir ce même instant vers New York donne 03 h, vers Kolkata 12 h 30, vers Tokyo 16 h et vers Sydney 17 h le 1er juillet. L’heure affichée change, mais l’instant reste le même.
| Opération | Entrée requise | Ce qui reste fixe |
|---|---|---|
tz_localize(zone) | Heure sans fuseau | Heure locale affichée |
tz_convert(zone) | Heure avec fuseau | Instant réel |
Convertir une valeur sans fuseau déclenche une erreur, car aucun fuseau de départ n’est connu. Localiser une valeur qui possède déjà un fuseau déclenche aussi une erreur ; utilise une conversion pour cette opération. Sur les colonnes, utilise .dt.tz_localize() et .dt.tz_convert(). Sur les index, utilise directement les méthodes ou les méthodes du DataFrame qui agissent sur l’index.
Lire du texte comportant des décalages et combiner les fuseaux
Un « Z » final dans un texte ISO signifie UTC. Pour du texte comportant différents décalages, effectue la conversion avec utc=True :
raw = pd.Series(["2025-03-01 10:00+01:00",
"2025-04-01 10:00+02:00"])
common = pd.to_datetime(raw, utc=True)
Ces valeurs deviennent 09 h et 08 h UTC. Convertis-les ensuite vers un fuseau régional pour les comptes rendus locaux. Dans pandas 3, convertir des valeurs avec des décalages différents sans utc=True déclenche une erreur.
Deux séries avec fuseau s’alignent selon les instants réels même lorsque leurs étiquettes de fuseau diffèrent. Des relevés à 09 h et 10 h à Amsterdam et à 08 h et 09 h à Londres en juillet correspondent aux mêmes instants. Le résultat de leurs calculs utilise des étiquettes UTC. Les comparaisons d’ordre entre horodatages sans fuseau et avec fuseau échouent ; le test d’égalité renvoie faux.
Retirer un fuseau délibérément
tz_convert(None) exprime d’abord une valeur avec fuseau en UTC, puis retire le fuseau. En juillet, 09 h à Amsterdam devient 07 h sans fuseau. tz_localize(None) retire le fuseau tout en conservant 09 h sans fuseau. Ce sont deux résultats différents. Conserve les données de calcul avec le fuseau UTC, puis convertis-les avant de présenter les résultats ou de les regrouper par jour local.
Points clés
- Localise les heures sans fuseau dans leur fuseau d’enregistrement.
- Convertis les horodatages avec fuseau pour afficher le même instant ailleurs.
- Les noms régionaux IANA conservent les règles d’heure d’été.
- Convertis les décalages différents en une représentation UTC commune.
- Retirer un fuseau peut conserver l’heure UTC ou l’heure locale affichée.
6.2 Gérer l’heure d’été dans les séries chronologiques
Les horloges locales peuvent sauter ou répéter une heure. Ces changements affectent la conversion des dates, les durées écoulées et les totaux quotidiens. Les fuseaux horaires nommés permettent à pandas de distinguer les instants réels derrière les heures locales affichées.
Reconnaître une heure locale sautée
Amsterdam est passée de 02 h à 03 h le 30 mars 2025. L’heure affichée 02 h 30 n’a jamais existé. La localiser sans règle déclenche une erreur :
pd.Timestamp("2025-03-30 02:30").tz_localize(
"Europe/Amsterdam", nonexistent="shift_forward"
)
Le résultat est 03:00+02:00, la première heure valide après la lacune. nonexistent="NaT" conserve le problème sous forme de valeur manquante. "shift_backward" déplace l’heure au dernier instant valide avant la lacune. Décaler un enregistrement modifie son horodatage : conserve donc l’entrée d’origine et documente la règle choisie dans l’analyse.
Distinguer deux heures affichées identiques
Le 26 octobre 2025, Amsterdam est repassée de 03 h à 02 h. L’heure locale 02 h 30 s’est produite une fois avec le décalage +02:00 et une fois avec +01:00. Ces deux instants sont espacés d’une heure en UTC.
ambiguous=True sélectionne l’occurrence à l’heure d’été ; ambiguous=False sélectionne celle à l’heure d’hiver. ambiguous="NaT" marque une heure non résolue comme manquante. Une liste de booléens permet de choisir pour chaque ligne. ambiguous="infer" peut utiliser une séquence ordonnée contenant l’heure répétée, comme 01 h 30, 02 h, 02 h 30, 02 h, 02 h 30, 03 h. Une heure affichée répétée mais isolée ne fournit pas assez d’indices d’ordre pour inférer l’occurrence voulue.
Compter les heures dans la journée locale
La journée du changement de printemps compte 23 heures et celle du changement d’automne en compte 25. Une série horaire complète rééchantillonnée par jour local présente donc des effectifs variables. Pour présenter l’énergie horaire moyenne, divise une somme quotidienne par le nombre réel de relevés horaires valides, ou calcule leur moyenne. Diviser chaque total par 24 donne un résultat erroné pour les jours de changement d’heure.
Un jeu de données partiel peut aussi créer des intervalles incomplets. Une série UTC commençant le 29 mars à 00 h commence à 01 h à Amsterdam : son premier jour local ne contient donc pas minuit, même avant le jour du changement d’heure. Vérifie les bornes du compte rendu ainsi que les règles du fuseau.
Distinguer même heure affichée et durée écoulée égale
t = pd.Timestamp("2025-03-29 12:00", tz="Europe/Amsterdam")
t + pd.offsets.Day(1) # March 30 at 12:00
t + pd.Timedelta(days=1) # March 30 at 13:00
Le décalage calendaire conserve midi et ne couvre que 23 heures écoulées. Le Timedelta ajoute 24 heures. En automne, un jour calendaire local peut au contraire contenir 25 heures écoulées.
Choisir le fuseau du compte rendu avant le regroupement
Le rééchantillonnage suit le fuseau de l’index. Pour totaliser la consommation par date locale d’Amsterdam, convertis d’abord un index UTC avec fuseau vers « Europe/Amsterdam », puis rééchantillonne en « D ». Rééchantillonner d’abord en UTC crée des bornes journalières différentes, qu’on ne peut pas corriger simplement en changeant les étiquettes du résultat.
Les dates de changement diffèrent selon les régions : New York a changé d’heure les 9 mars et 2 novembre en 2025 ; Sydney a terminé l’heure d’été le 6 avril et l’a commencée le 5 octobre. Tokyo et Kolkata ne changent pas d’heure. Conserve les instants bruts en UTC et utilise le fuseau local nommé pour les comptes rendus calendaires.
Points clés
- Les heures sautées et répétées nécessitent des règles de localisation explicites.
- Une heure locale ambiguë peut désigner deux instants UTC distincts.
- Des journées locales complètes peuvent contenir 23 ou 25 heures.
- Convertis vers le fuseau du compte rendu avant de regrouper par jour local.
- Distingue les changements d’heure d’une couverture incomplète des données.
Séries chronologiques avec pandas : exemples
1Transformer un journal textuel en dates utilisables
11 étapes
- 1IntroductionCommencer avec une colonne de dates
Un journal de compteur arrive avec des dates écrites sous forme de texte. Tu as besoin de dates que pandas peut comparer, du temps écoulé entre les enregistrements et d’étiquettes lisibles pour un compte rendu. Il faut donc un Timestamp pour chaque instant, un Timedelta pour le temps écoulé et du texte mis en forme seulement à la fin.
Effectue la conversion avant de calculer. Une chaîne peut ressembler à une date sans se comporter comme une date calendaire, et un format ambigu peut produire une date plausible mais incorrecte.
- 2ExempleLire la convention d’origine
Le journal indique que les dates commencent par le jour et que l’heure est sur 24 heures. Une entrée est « 14/03/2025 18:45 ». Son format est :
format="%d/%m/%Y %H:%M"Lis les codes dans l’ordre : jour, mois, année, heure et minute.
%met%Mdiffèrent par la casse car ils représentent des champs différents. La date est le 14 mars ; l’heure est 18 h 45. - 3ExplicationAppliquer un format connu
Convertis la colonne avec le format documenté :
parsed = pd.to_datetime(raw, format="%d/%m/%Y %H:%M", errors="coerce")Le format s’applique à chaque entrée non manquante. La coercition transforme les entrées invalides en
NaT. Sans format connu, pandas infère celui-ci à partir de la première ligne non manquante ; une source contenant des dates ambiguës avec des barres obliques risque alors d’être mal interprétée. - 4DéfiCompter les échecs réels
Une colonne contient « 14/03/2025 18:45 », « bad » et
None. Après coercition, deux résultats sontNaT. Combien de valeurs présentes n’ont pas pu être converties et quel masque permet de les trouver ?---reveal---
Une valeur présente n’a pas pu être convertie : « bad ». Utilise
parsed.isna() & raw.notna(). LeNoned’origine était déjà manquant : compter tous lesNaTsurestimerait donc les échecs de conversion. - 5ExplicationDistinguer instants et durées
Un Timestamp représente un instant et une colonne datetime contient plusieurs instants. Un Timedelta représente un temps écoulé.
Soustrais un Timestamp de début d’un Timestamp de fin pour obtenir une durée. Ajoute un Timedelta pour déplacer un instant d’une durée fixe.
NaTmarque les instants manquants : un calcul faisant intervenir un début ou une fin manquante produit donc aussi une durée manquante. - 6ExempleSoustraire les deux instants
Prends ces horodatages :
start = pd.Timestamp("2025-03-10 18:00") end = pd.Timestamp("2025-03-14 09:30") elapsed = end - startLe résultat est de 3 jours et 15 h 30. Compte d’abord les trois jours entiers, puis les 15 heures 30 minutes restantes. Conserver ce résultat sous forme de Timedelta permet à l’étape suivante de choisir l’unité de présentation voulue sans perdre ce reste.
- 7ExempleConvertir toute la durée en heures
Trois jours représentent 72 heures. Le reste représente 15,5 heures, donc le total est de 87,5 heures.
hours = elapsed / pd.Timedelta(hours=1)elapsed.daysne donne que 3. Cet attribut décrit la composante en jours entiers : la multiplier par 24 ferait donc perdre 15,5 heures.total_seconds()donne 315 000 et inclut aussi toute la durée. - 8DéfiChoisir une composante calendaire utile
Un compte rendu nécessite la moyenne des kWh par jour de la semaine sur plusieurs semaines. Quelle composante calendaire peut fournir la clé de regroupement et une colonne nécessite-t-elle
.dt?---reveal---
Utilise
df["timestamp"].dt.day_name()comme clé de regroupement, puis calcule la moyenne dekwh. Une colonne datetime nécessite.dt; un DatetimeIndex donne directement accès àday_name(). Cela regroupe les jours de la semaine récurrents, pas des dates calendaires distinctes. - 9ConseilVérifier les unités avant l’exportation en entiers
Un type datetime comme
datetime64[us]stocke des décomptes en microsecondes. Une conversion directe en entiers renvoie ces décomptes, même si du code plus ancien attend des nanosecondes.Pour une colonne, demande explicitement
s.dt.as_unit("ns").astype("int64")lorsque des décomptes en nanosecondes sont nécessaires. Pour comparer des durées, conserve les calculs sur les Timedelta afin que l’unité accompagne la valeur. - 10DéfiPréparer le compte rendu final
Tu as converti les dates et calculé les heures écoulées. Le compte rendu nécessite des dates comme « 14 Mar 2025 ». Faut-il mettre en forme la colonne de dates avant de calculer et quelle expression produit cette étiquette ?
---reveal---
Termine d’abord les calculs datetime, puis utilise
parsed.dt.strftime("%d %b %Y")pour les étiquettes d’affichage. La mise en forme renvoie du texte. Le nom de mois abrégé suit les paramètres régionaux du système ; cet exemple utilise l’anglais. - 11RécapitulatifChoisir la représentation selon l’objectif
Utilise les valeurs datetime pour les sélections et les calculs calendaires, les Timedelta pour les durées écoulées et les chaînes mises en forme pour les étiquettes finales. C’est lors de la conversion que les conventions d’origine prennent un sens calendaire.
Avant de transmettre une colonne convertie à l’étape suivante, examine les entrées non manquantes dont la conversion a échoué, son type de données et les unités de sortie requises. L’analyse ultérieure dispose ainsi d’une représentation temporelle claire.
2Construire un historique propre et comparer les bonnes dates
13 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDonner une identité temporelle claire à chaque ligne
- 2ExempleConvertir, indexer et trier
- 3ConseilTraiter les événements répétés selon leur sens
- 4DéfiFaire apparaître une date absente
- 5ExplicationLire la précision d’un sélecteur
- 6DéfiSélectionner une plage de travail récurrente
- 7ExemplePlacer le prédécesseur à côté de chaque valeur
- 8Point cléUne fraction de croissance n’est pas un pourcentage affiché
- 9ExplicationDécaler les dates pour une comparaison calendaire
- 10DéfiSuivre l’alignement des étiquettes
- 11LienGarder distinct le prédécesseur de chaque magasin
- 12DéfiCorriger un compte rendu de croissance quotidienne
- 13RécapitulatifVérifier les étiquettes avant d’interpréter une variation
3Construire des calendriers et étiqueter des périodes complètes
12 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDéterminer ce qu’une date doit représenter
- 2ExempleGénérer des dates de fin de mois
- 3ConseilAssocier l’alias au calendrier
- 4DéfiCompter les bornes d’une séquence
- 5ExempleAvancer d’un mois à partir du 31 janvier
- 6ExplicationComprendre un point d’ancrage déjà atteint
- 7DéfiChoisir entre temps ouvré et temps écoulé
- 8ExplicationÉtiqueter les totaux mensuels avec des périodes
- 9ExempleConvertir une date en mois et inversement
- 10DéfiLire une étiquette d’exercice
- 11DéfiChoisir entre des instants mensuels et des périodes mensuelles
- 12RécapitulatifLaisser la règle calendaire exprimer le sens
4Créer des comptes rendus quotidiens et mensuels à partir d’observations
13 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDéterminer le sens de la nouvelle fréquence
- 2ExempleAgréger deux grandeurs différemment
- 3ExplicationSuivre un intervalle de cinq minutes
- 4DéfiDéplacer l’observation à la borne
- 5ConseilVérifier les intervalles vides et incomplets
- 6ExempleCréer une grille quotidienne plus fine
- 7ExempleCombler une lacune de trois façons
- 8DéfiConserver ce qui était connu
- 9Point cléUn point échantillonné n’est pas un total
- 10ExempleGarder chaque magasin dans ses propres intervalles
- 11DéfiExpliquer un mois vide pour un magasin
- 12DéfiCorriger un tableau de comparaison
- 13RécapitulatifComprendre ce qu’affirme chaque ligne du résultat
5Suivre les observations dans chaque fenêtre
16 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionChoisir la part d’historique qui compte
- 2ExempleConstruire la première fenêtre complète de lignes
- 3ExempleAvancer d’une ligne
- 4DéfiCompter les valeurs valides dans les positions
- 5ConseilPlacer les résultats correctement dans le temps
- 6ExplicationUtiliser le temps écoulé pour des événements irréguliers
- 7ExempleSuivre la borne gauche exclue
- 8DéfiModifier la borne et le nombre d’observations requis
- 9Point cléUn mois n’est pas une durée de fenêtre glissante
- 10ExempleConserver tout l’historique
- 11ExempleComparer une valeur à son maximum antérieur
- 12ExempleMettre à jour une moyenne pondérée récursive
- 13ExplicationComprendre le réglage de correction
- 14DéfiDistinguer pondération et paire récente
- 15DéfiChoisir l’historique conservé dans un compte rendu
- 16RécapitulatifIdentifier la fenêtre avant de lire le résultat
6Faire correspondre les instants entre fuseaux et changements d’heure
12 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDistinguer l’heure affichée de l’instant
- 2ExplicationLocaliser une heure sans fuseau
- 3ExempleConvertir un événement vers plusieurs heures locales
- 4ConseilConserver les règles régionales
- 5DéfiChoisir comment retirer un fuseau
- 6ExplicationTraiter une heure sautée au printemps
- 7ExplicationDistinguer deux occurrences en automne
- 8DéfiRésoudre l’ambiguïté de l’heure répétée
- 9ExempleCompter une journée locale complète
- 10ExempleDistinguer midi demain de 24 heures écoulées
- 11DéfiCorriger le compte rendu quotidien local
- 12RécapitulatifPréciser l’instant et la borne du compte rendu
Séries chronologiques avec pandas : QCM
Série 1 : Convertir, sélectionner et synthétiser des dates10 Questions Pratiques
Question 1 sur 10
Afficher la réponseMasquer la réponse
.days du Timedelta conserverait 24 heures et ferait perdre les 6,5 heures restantes. Divise la durée par pd.Timedelta(hours=1) pour tenir compte de toute sa longueur.Question 2 sur 10
Afficher la réponseMasquer la réponse
%d/%m/%Y conserve donc le 7 novembre. %H:%M lit l’heure sur 24 heures et les minutes. Une conversion plaçant le mois en premier produirait le 11 juillet, une date valide mais de sens incorrect : une conversion réussie ne suffit donc pas à elle seule.Question 3 sur 10
Afficher la réponseMasquer la réponse
sort_index() établit l’ordre chronologique nécessaire à une sélection temporelle fiable. Supprimer des doublons ne résoudrait pas le problème, car l’index indiqué ne contient aucun horodatage répété.Question 4 sur 10
.loc["2025-07-08 09:00":"2025-07-08 12:00"] sélectionne-t-il ?Afficher la réponseMasquer la réponse
.iloc exclurait 12 h et donnerait trois lignes. Les tranches par étiquettes datetime incluent les deux bornes lorsque les lignes correspondantes sont présentes.Question 5 sur 10
pd.date_range("2025-08-19", periods=3, freq="MS") ?Afficher la réponseMasquer la réponse
MS exige des débuts de mois : la première date correspondante égale ou postérieure au 19 août est donc le 1er septembre. Le 1er août est déjà antérieur au début fourni. La séquence n’inclut pas le 19 août simplement parce que cette date a été passée comme borne de début.Question 6 sur 10
pd.DateOffset(months=1) produit-il ?Afficher la réponseMasquer la réponse
Question 7 sur 10
Afficher la réponseMasquer la réponse
Question 8 sur 10
Afficher la réponseMasquer la réponse
Question 9 sur 10
s = pd.Series([3, 9, 6, 12]), quelle est la dernière valeur de s.rolling(3).mean() ?Afficher la réponseMasquer la réponse
Question 10 sur 10
Afficher la réponseMasquer la réponse
Série 2 : Comparer les historiques et les résultats des fenêtres10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
.dt.day_of_week pour une observation du dimanche ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
pct_change() pour le mercredi ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
freq="Q-SEP". Quel intervalle pd.Period("2026Q1", freq="Q-SEP") décrit-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
resample("5min", closed="right", label="right").sum() ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
[2, NaN, 8, 14], quels sont les deux derniers résultats de rolling(3, min_periods=2).mean() ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
rolling("3D").sum() ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
s / s.cummax() - 1 ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 3 : Choisir la bonne opération calendaire10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
["2025-09-02", None, "2025-15-02", "bad"]. Elle est convertie avec format="%Y-%m-%d", errors="coerce". Combien de valeurs présentes dans la source n’ont pas pu être converties ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
.loc["2025-12-02":"2025-12-03"] ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
pd.date_range("2025-06-10", "2025-06-11", freq="6h") avec l’inclusion des bornes par défaut ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
.to_timestamp(). Que deviennent les étiquettes et leur unicité ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
pd.Grouper ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
rolling("3D", min_periods=2) avec les bornes par défaut ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
ewm(span=3, adjust=False) ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
ambiguous=True, l’autre avec ambiguous=False. Quel est leur écart après conversion en UTC ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 4 : Diagnostiquer les calculs sur les séries chronologiques10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
datetime64[us]. Une exportation nécessite des décomptes entiers en nanosecondes. Quelle expression de colonne fournit ces décomptes ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
1735689600000 en millisecondes. Quels arguments de conversion préservent l’unité et le fuseau indiqués ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
a contient 30 le 1er août et 50 le 4 août. Tu calcules a - a.shift(1, freq="D"). Quelles valeurs apparaissent les 2 et 4 août ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
MonthEnd(0) et celui de MonthEnd(1) ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
.asfreq("D", how="end"), puis avec .to_timestamp() et ses paramètres par défaut. Quel horodatage obtient-on ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
freq="B" du vendredi 12 septembre au lundi 15 septembre 2025. Aucun jour férié personnalisé n’est fourni. Quelles dates apparaissent ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
asfreq("D"). Pourquoi la valeur présentée n’est-elle pas le total d’énergie quotidien ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
rolling(5, center=True).mean() et pour la fenêtre rétrospective par défaut rolling(5).mean() ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
tz_convert(None) et de tz_localize(None), dans cet ordre ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 5 : Combiner les règles temporelles dans des analyses complètes10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
["2025-12-02", "03/12/2025"] et indique que les dates avec barres obliques commencent par le jour. Quelle interprétation le nettoyage doit-il préserver ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
pct_change() par groupe, puis avec un calcul simple sur toute la colonne ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
resample("D").sum(min_count=1) ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Tu bloques sur ton propre exercice ? Aide aux Devoirs
Mots-Clés
A
Accesseur .dt
.dt donne accès aux fonctionnalités de dates, d’heures et de durées d’une colonne pandas, notamment aux composantes calendaires, à l’arrondi et à la conversion d’unité..dt dans readings["time"].dt.hour fournit l’heure enregistrée pour le regroupement.Alias de fréquence
"15min" génère des étiquettes tous les quarts d’heure, tandis que "ME" génère des fins de mois.Alignement des horodatages
Analyse de dates de formats différents
asfreq
asfreq() place une série sur une nouvelle grille en sélectionnant les horodatages correspondants, sans agréger les observations intermédiaires.asfreq() quotidien sur des données horaires conserve les relevés de minuit sans additionner les valeurs de la journée.Avance
shift(-1) permet à une table de comparer chaque événement au prochain événement enregistré.B
Borne de période
Borne gauche exclue
C
Coefficient de lissage
Coercition
NaT, ce qui permet de terminer la conversion tout en marquant les valeurs invalides comme manquantes.Conversion de fréquence des périodes
how="end" peut sélectionner la dernière période quotidienne d’un mois.Conversion de fuseau horaire
Corrélation glissante
D
DateOffset
DatetimeIndex
.loc de sélectionner un mois entier pour un compte rendu.Décalage MonthEnd
Décalage par rapport à UTC
Désempilement
Drawdown
É
Étiquette d’intervalle
E
Effectif de la fenêtre
F
Fenêtre centrée
Fenêtre croissante
Fenêtre de durée fixe
Fenêtre glissante
Fenêtre rétrospective
Fenêtre temporelle
Fermeture des intervalles
Format d’analyse des dates
"%d/%m/%Y" lit « 08/11/2025 » comme le 8 novembre plutôt que le 11 août.Fréquence ancrée
Fréquence en jours ouvrés
Fréquence inférée
Fréquence par semaine du mois
"WOM-3FRI" crée des dates récurrentes le troisième vendredi de chaque mois.H
Heure d’été
Heure locale ambiguë
Heure locale inexistante
Horodatage avec fuseau horaire
Horodatage en double
Horodatage sans fuseau horaire
Horodatage Unix
unit="ms", même si un décompte en secondes lui ressemble.I
Inclusion des bornes
Index monotone
Indexation par chaîne partielle
"2025-09" conserve les observations horaires de tout le mois de septembre.Interpolation linéaire
Intervalle journalier en heure locale
Intervalle temporel
ISO 8601
J
Jour calendaire
L
Lacune calendaire
Localisation
M
Masque calendaire
Maximum cumulé
min_periods
min_periods définit le nombre de valeurs valides dont une fenêtre a besoin pour produire un résultat, sans compter les cellules manquantes.min_periods=2, mais pas min_periods=3.Moyenne mobile à pondération exponentielle
MultiIndex
N
NaT
pd.isna().NaT, tout comme les entrées déjà manquantes.Nom de fuseau horaire IANA
Normalisation
O
Objet Grouper temporel
groupby, aux côtés d’autres clés comme le magasin ou le capteur.OHLC
P
Period
PeriodIndex
Plage horaire
Propagation de la dernière valeur connue
Propagation de la prochaine valeur connue
R
Rééchantillonnage
Rééchantillonnage par groupe
Règle de localisation
Résolution temporelle
Retard
Retard de lissage
Rollback
rollback() d’un décalage trouve le point d’ancrage calendaire valide le plus proche égal ou antérieur à une date, et conserve une date déjà sur ce point.rollback() d’une règle MonthEnd déplace le 15 janvier au 31 décembre de l’année précédente.Rollforward
rollforward() d’un décalage trouve le point d’ancrage calendaire valide le plus proche égal ou postérieur à une date, et conserve une date déjà sur ce point.rollforward() d’une règle MonthEnd déplace le 15 janvier au 31 janvier de la même année.S
Séquence de dates
Série chronologique
Somme cumulée
Sous-échantillonnage
strftime
strftime transforme les valeurs datetime en texte d’affichage à l’aide de codes de format, en remplaçant leur représentation datetime par des chaînes.strftime pour afficher « 17 Aug 2025 » après avoir terminé ses calculs datetime.Suréchantillonnage
T
Timedelta
Timestamp
Tranche par étiquettes à bornes incluses
Trimestre de l’exercice
U
UTC
V
Variation relative
À propos de cette unité
Crée ton propre Matériel d'Étude
Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.