Décalages et variables retardées
Créez des colonnes retardées et avancées avec shift(), calculez la variation d’une période à l’autre avec diff() et calculez la variation en pourcentage.
Décalages et variables retardées est une leçon Pandas & NumPy Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Pandas & NumPy Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Pandas & NumPy Academy comprend 4 leçons au total.
Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.
Why Lag Features Matter
In time series analysis, the value at a previous time step (a lag) is often one of the best predictors of the current value. For example, yesterday's sales are informative about today's sales. Creating lag columns lets you use historical values as features in machine learning models or in statistical analysis of autocorrelation. Pandas provides shift() to create lag features in a single vectorised call.
shift(): Moving Values Forward or Backward
Series.shift(n) moves all values down by n positions (positive n creates a lag), filling the first n rows with NaN. Passing a negative n moves values up (creates a lead, shifting future values back to the current row). The index remains unchanged — only the values are displaced.
import pandas as pd
import numpy as np
df = pd.DataFrame(
{'sales': [100, 120, 115, 130, 140, 125]},
index=pd.date_range('2024-01-01', periods=6, freq='D')
)
# Lag-1: yesterday's sales
df['sales_lag1'] = df['sales'].shift(1)
# Lead-1: tomorrow's sales (shifted up)
df['sales_lead1'] = df['sales'].shift(-1)
print(df)Creating Multiple Lag Columns
You typically create several lag features at once for machine learning — lag-1, lag-7 (same day last week), and lag-30 (same day last month). The most readable way is to create them in a loop and assign each to a new column. The resulting DataFrame has the original series plus all its lagged versions ready for modelling.
for lag in [1, 2, 3, 7]:
df[f'sales_lag{lag}'] = df['sales'].shift(lag)
print(df.columns.tolist())
# ['sales', 'sales_lag1', 'sales_lag2', 'sales_lag3', 'sales_lag7']
# Drop rows with NaN from the largest lag period
df_model = df.dropna()
print('Ready for modelling, shape:', df_model.shape)shift() with freq for Time-Based Shifting
Instead of shifting by an integer number of rows, you can shift by a time offset using the freq parameter. df.shift(1, freq='ME') shifts the index forward by one month-end, keeping the values in place but changing the index. This is useful for aligning two time series that are offset by a fixed time period without rearranging the values.
monthly = pd.Series(
[100, 120, 115],
index=pd.date_range('2024-01-31', periods=3, freq='ME')
)
# Shift the index forward by 1 month (values stay, index moves)
shifted_index = monthly.shift(1, freq='ME')
print('Original index:', monthly.index.tolist())
print('Shifted index: ', shifted_index.index.tolist())
# Original: [2024-01-31, 2024-02-29, 2024-03-31]
# Shifted: [2024-02-29, 2024-03-31, 2024-04-30]diff(): Period-over-Period Change
Series.diff(n) computes the difference between a value and the value n positions before it: x[t] - x[t-n]. This is commonly used to compute day-over-day changes, week-over-week differences, or year-over-year deltas. The first n rows are NaN since there are no previous values to subtract from.
df['sales_diff1'] = df['sales'].diff(1) # day-over-day change
df['sales_diff7'] = df['sales'].diff(7) # week-over-week change
print(df[['sales', 'sales_diff1']].head())
# sales sales_diff1
# 2024-01-01 100 NaN
# 2024-01-02 120 20.0 <- +20 from yesterday
# 2024-01-03 115 -5.0 <- -5 from yesterdaypct_change(): Percentage Change
Series.pct_change(n) computes the relative percentage change: (x[t] - x[t-n]) / x[t-n]. This is essential for financial analysis (daily returns), growth rate computation, and any situation where the absolute change is less meaningful than the relative change. Multiply by 100 to get percentage points.
df['pct_chg'] = df['sales'].pct_change().round(3)
df['pct_chg_7d'] = df['sales'].pct_change(7).round(3)
print(df[['sales', 'pct_chg']].head())
# sales pct_chg
# 2024-01-01 100 NaN
# 2024-01-02 120 0.200 <- 20% increase
# 2024-01-03 115 -0.042 <- 4.2% decreaseCombining shift() with Arithmetic
You can combine shift() with arithmetic to compute derived time features. For example: the ratio of today's value to last week's value, the cumulative sum since a fixed start, or the difference from the year-ago value. All of these follow the same pattern: shift the original series and perform element-wise arithmetic with the current values.
# Week-over-week growth index (today / last week)
df['wow_ratio'] = (df['sales'] / df['sales'].shift(7)).round(3)
# Deviation from 3-day lag
df['dev_3d'] = df['sales'] - df['sales'].shift(3)
# Is today higher than yesterday? (boolean feature)
df['higher_than_yesterday'] = df['sales'] > df['sales'].shift(1)
print(df[['sales', 'wow_ratio', 'higher_than_yesterday']].head())cumsum() and cumprod() for Cumulative Features
Series.cumsum() computes the running total from the first row up to each row, while Series.cumprod() computes the cumulative product. These are useful for cumulative revenue, cumulative returns (compound growth), and year-to-date totals. They require no arguments and work on any numeric Series or DataFrame column.
# Cumulative sales (year-to-date total)
df['ytd_sales'] = df['sales'].cumsum()
# Cumulative product: compound growth factor
returns = pd.Series([0.02, -0.01, 0.03, 0.01, -0.005])
df_ret = pd.DataFrame({'daily_return': returns})
df_ret['compound'] = (1 + df_ret['daily_return']).cumprod() - 1
print(df_ret)Lag Features for Machine Learning
When preparing time series data for machine learning, a standard feature engineering step is to create a matrix of lag features. Each column represents the target variable at a different past time step. After creating lags, drop rows with NaN (which appear at the start due to missing history) and split into train and test sets without shuffling, respecting the temporal order.
def make_lag_matrix(series, n_lags):
df_lags = pd.DataFrame({'y': series})
for lag in range(1, n_lags + 1):
df_lags[f'lag_{lag}'] = series.shift(lag)
return df_lags.dropna()
lag_df = make_lag_matrix(df['sales'], n_lags=3)
print(lag_df)
# y lag_1 lag_2 lag_3
# ... ... ... ...Shifting Within Groups
When your data contains multiple entities (e.g., multiple products or regions in one DataFrame), you must compute shifts within each entity's group separately. Use groupby().shift() to ensure that the lag for product A's first row is NaN and not the last value of product B. Mixing groups without this step is a common and subtle data leakage bug.
df_multi = pd.DataFrame({
'product': ['A', 'A', 'A', 'B', 'B', 'B'],
'sales': [100, 120, 115, 200, 210, 195]
})
# WRONG: lag crosses product boundary
df_multi['lag_wrong'] = df_multi['sales'].shift(1)
# CORRECT: lag within each product
df_multi['lag_correct'] = df_multi.groupby('product')['sales'].shift(1)
print(df_multi)Interpreting pct_change Signs
A positive pct_change() value means the current value is higher than the previous one; a negative value means it is lower. Watch out for division-by-zero when the previous value is zero — the result is NaN or inf depending on the sign of the current value. Use replace([float('inf'), float('-inf')], float('nan')) to clean infinite values after pct_change().
import numpy as np
s = pd.Series([0, 100, 50, 200])
chg = s.pct_change()
print(chg)
# 0 NaN <- no prior value
# 1 inf <- 0 -> 100 (division by zero)
# 2 -0.5 <- 100 -> 50 (-50%)
# 3 3.0 <- 50 -> 200 (+300%)
# Clean infinite values
chg_clean = chg.replace([float('inf'), float('-inf')], float('nan'))
print(chg_clean)Quick Check
Test your understanding of shifting and lag features from this lesson.
Lesson Recap
In this lesson you learned: shift(n) creates lag features by moving values down by n positions; diff(n) computes period-over-period absolute change; pct_change(n) computes relative percentage change; and when working with multiple groups you must use groupby().shift() to avoid data leakage. Next up we extract temporal features using the .dt accessor.
Questions Fréquemment Posées
La leçon « Décalages et variables retardées » est-elle gratuite ?
Oui — le texte complet de « Décalages et variables retardées » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Pandas & NumPy Academy, passe à CoddyKit PRO. Le cours Pandas & NumPy Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Décalages et variables retardées » ?
Créez des colonnes retardées et avancées avec shift(), calculez la variation d’une période à l’autre avec diff() et calculez la variation en pourcentage. Tu pratiques Pandas & NumPy Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Pandas & NumPy Academy ?
Aucune expérience préalable n'est requise. Pandas & NumPy Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Décalages et variables retardées » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Pandas & NumPy Academy ?
Oui. Chaque leçon Pandas & NumPy Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- DatetimeIndex et intervalles de périodes
- Rééchantillonner des séries temporelles
- Décalages et variables retardées
- Extraire des caractéristiques temporelles