Les dates ne sont pas des chaînes
Une série de prix est une série temporelle : ce qui compte, c'est quand chaque prix s'est produit. Les dates lues dans un fichier sont de simples chaînes, et une chaîne ne sait pas que mars vient après février ni qu'un lundi suit un dimanche. Convertissez-les avec pd.to_datetime et utilisez le résultat comme index : un DatetimeIndex contient de vrais horodatages que pandas sait trier, découper, comparer et décomposer. Triez-le toujours (sort_index()) pour que l'observation la plus ancienne vienne en premier.
import pandas as pd
raw_dates = ["2026-03-04", "2026-03-02", "2026-03-03"] # strings, in a messy order
closes = [102.0, 100.0, 101.0]
series = pd.Series(closes, index=pd.to_datetime(raw_dates), name="close").sort_index()
print(series)
# 2026-03-02 100.0
# 2026-03-03 101.0
# 2026-03-04 102.0
# Name: close, dtype: float64
print(isinstance(series.index, pd.DatetimeIndex)) # TrueConstruire un calendrier
On a souvent besoin de dates que personne ne vous a données : une grille de comparaison, ou les jours d'un backtest. pd.date_range(start, periods=n, freq="D") produit n jours calendaires consécutifs, et pd.bdate_range saute les week-ends et donne des jours ouvrés. (Il ignore les jours fériés.) L'argument freq règle le pas : "D" est un jour, "B" un jour ouvré, "h" une heure.
# Four calendar days, then six business days (the weekend is skipped)
print(pd.date_range("2026-03-01", periods=4, freq="D").strftime("%a %d %b").tolist())
# ['Sun 01 Mar', 'Mon 02 Mar', 'Tue 03 Mar', 'Wed 04 Mar']
days = pd.bdate_range("2026-02-26", periods=6)
print(days.strftime("%a %d %b").tolist())
# ['Thu 26 Feb', 'Fri 27 Feb', 'Mon 02 Mar', 'Tue 03 Mar', 'Wed 04 Mar', 'Thu 05 Mar']Sélectionner par date
Avec un DatetimeIndex trié, .loc comprend les dates écrites en chaînes. Une chaîne partielle comme "2026-03" sélectionne tout le mois, "2026" toute l'année et "2026-03-04" un seul jour. Une tranche .loc["2026-03-04":"2026-03-06"] sélectionne une plage et, contrairement à une tranche de positions, les deux bornes sont incluses. Les bornes n'ont pas besoin d'exister dans les données : les dates de week-end ne correspondent à rien, ce qui est voulu quand on demande « tout depuis le premier du mois ».
prices = pd.Series(
[float(i) for i in range(20)],
index=pd.bdate_range("2026-02-23", periods=20), # Mon 23 Feb ... Fri 20 Mar
)
print(len(prices.loc["2026-03"])) # 15 the business days of March in the data
print(prices.loc["2026-03-04"]) # 7.0 a single day
print(prices.loc["2026-03-04":"2026-03-06"])
# 2026-03-04 7.0
# 2026-03-05 8.0
# 2026-03-06 9.0
# Freq: B, dtype: float64
print(prices.loc["2026-03-01":"2026-03-03"].tolist()) # [5.0, 6.0] Sunday the 1st matches nothingLes composantes d'une date
Un DatetimeIndex expose les composantes de chaque date comme attributs : year, month, day, dayofweek (le lundi vaut 0, le dimanche 6). Chacune est un tableau avec une entrée par ligne, utilisable comme masque ou comme clé de groupe. C'est ainsi que l'on demande « combien d'observations tombent chaque jour de la semaine ? » ou « que se passe-t-il le lundi ? » sans boucle. N'oubliez pas de trier l'index d'abord : découper un DatetimeIndex désordonné peut donner des résultats surprenants ou une erreur.
# The parts of the dates, one entry per row
print(prices.index.dayofweek[:7].tolist()) # [0, 1, 2, 3, 4, 0, 1] Monday is 0
print(prices.index.month[:7].tolist()) # [2, 2, 2, 2, 2, 3, 3]
# How many observations fall on each weekday?
print(prices.groupby(prices.index.dayofweek).size().to_dict()) # {0: 4, 1: 4, 2: 4, 3: 4, 4: 4}
# What do the Mondays look like?
print(prices[prices.index.dayofweek == 0].tolist()) # [0.0, 5.0, 10.0, 15.0].loc["2026-03-04":"2026-03-06"] inclut le 6, mais avec des données intrajournalières il s'arrête à 00:00 le 6 et perd toute la journée. Vérifiez le dernier horodatage du résultat quand vos données sont plus fines qu'un jour.pd.to_datetime(chaînes)crée un DatetimeIndex ;sort_index()met le plus ancien en premier ;date_rangeetbdate_rangeconstruisent des calendriers..loc["2026-03"]sélectionne un mois,.loc["2026-03-04":"2026-03-06"]une plage, bornes incluses.index.year,index.month,index.dayofweekdonnent les composantes de chaque date, pour filtrer ou grouper sans boucle.
À suivre : le rééchantillonnage, qui transforme des prix quotidiens en barres hebdomadaires, mensuelles ou plus fines.
Lab : ce qui est noté
- Construire une série de prix datée avec
parse_prices25 pts - Sélectionner un mois avec
prices_in_month25 pts - Sélectionner une plage de dates avec
prices_between25 pts - Compter les observations par jour de la semaine avec
count_by_weekday25 pts