AccueilBlogPython data avancé
Guide recrutement data

Test technique Python data avancé : pandas, DuckDB, Polars, optimisation

Au-delà des bases de pandas, un Data Engineer Senior maîtrise la vectorisation, la gestion mémoire, et sait quand remplacer pandas par DuckDB ou Polars pour des performances 10x à 100x supérieures.

Data Builder·Juin 2025·9 min de lecture·Data Engineer · Data Scientist
Sommaire
  1. pandas : pièges et anti-patterns
  2. Optimisation mémoire
  3. Vectorisation vs boucles
  4. DuckDB : SQL sur DataFrames
  5. Polars : le successeur de pandas ?
  6. Profiling et diagnostic
  7. Grille par niveau

Un Data Engineer qui utilise des boucles iterrows() sur des DataFrames pandas en production livre de la dette technique. Les pièges de performance, la vectorisation et la maîtrise de DuckDB ou Polars sont les vrais discriminants en entretien.

1pandas : les pièges classiques

Question discriminante

Quelle est la différence entre .loc, .iloc et .at ? Pourquoi faut-il absolument éviter iterrows() sur un grand DataFrame ?

# MAUVAIS : boucle Python sur un DataFrame (tres lent) for index, row in df.iterrows(): df.at[index, 'profit'] = row['revenue'] - row['cost'] # BON : vectorisation directe df['profit'] = df['revenue'] - df['cost'] # BON : np.where pour les conditions simples import numpy as np df['tier'] = np.where(df['amount'] > 1000, 'gold', np.where(df['amount'] > 100, 'silver', 'bronze')) # Selection par label vs position df.loc[df['status'] == 'active', 'revenue'] # par label/condition df.iloc[0:10, 2:5] # par position entiere df.at[42, 'revenue'] # acces scalaire rapide par label

Signal GO Senior : le candidat cite spontanement iterrows() comme anti-pattern, explique la vectorisation et connait np.where.

2Optimisation memoire : reduire la taille des DataFrames

Question discriminante

Comment reduisez-vous la consommation memoire d'un DataFrame pandas de 3 Go ?

import pandas as pd # Diagnostic memoire print(df.memory_usage(deep=True).sum() / 1024**2, "MB") # Reduction des types numeriques df['age'] = df['age'].astype('int8') # int64 -> int8 : 8x moins df['score'] = df['score'].astype('float32') # float64 -> float32 : 2x moins df['status'] = df['status'].astype('category') # string -> category : -80% df['pays'] = df['pays'].astype('category') # Types specifies a l'import (optimal) df = pd.read_csv("data.csv", dtype={ 'age': 'int8', 'status': 'category', 'amount': 'float32' }) # Lecture par chunks pour les tres gros fichiers for chunk in pd.read_csv("big_file.csv", chunksize=100_000): process(chunk)

3Vectorisation et NumPy : pourquoi c'est plus rapide

Question discriminante

Expliquez pourquoi une operation vectorisee NumPy est 500x plus rapide qu'une boucle Python equivalente.

import numpy as np # Boucle Python : ~5 secondes sur 1M de lignes distances = [] for i in range(len(df)): d = np.sqrt(df['x'].iloc[i]**2 + df['y'].iloc[i]**2) distances.append(d) # Vectorisation NumPy : ~10 millisecondes (500x plus rapide) distances = np.sqrt(df['x']**2 + df['y']**2) # pd.cut pour les decoupages en tranches df['age_group'] = pd.cut(df['age'], bins=[0, 18, 35, 50, 100], labels=['junior', 'adulte', 'senior', 'aine'] )

4DuckDB : SQL sur des DataFrames et des fichiers Parquet

Question discriminante

Dans quel cas utilisez-vous DuckDB plutot que pandas ? Quelle est sa principale force sur les fichiers Parquet ?

import duckdb # DuckDB lit directement les fichiers Parquet sans tout charger en RAM result = duckdb.sql(""" SELECT country, SUM(revenue) AS total_revenue, COUNT(*) AS nb_orders FROM 'data/orders_*.parquet' WHERE order_date >= '2024-01-01' GROUP BY country ORDER BY total_revenue DESC LIMIT 20 """).df() # convertit en DataFrame pandas si necessaire # DuckDB peut aussi requeter directement un DataFrame pandas existant conn = duckdb.connect() result = conn.execute(""" SELECT customer_id, SUM(amount) AS total FROM df_orders GROUP BY customer_id HAVING total > 1000 """).df()

Alternative zero-installation : DuckDB fonctionne en process sans serveur. pip install duckdb et c'est pret. Idéal pour les scripts ETL locaux sur des fichiers volumineux.

5Polars : performances maximales, API lazy

Question discriminante

Quelle est la difference entre l'API eager et lazy de Polars ? Quand migrer de pandas vers Polars ?

import polars as pl # API Eager : execution immediate (comme pandas) df = pl.read_csv("data.csv") result = ( df .filter(pl.col("amount") > 100) .group_by("category") .agg(pl.col("amount").sum().alias("total")) ) # API Lazy : execution differee et optimisee (comme Spark) result = ( pl.scan_csv("data.csv") # scan = lecture lazy .filter(pl.col("amount") > 100) .group_by("category") .agg(pl.col("amount").sum().alias("total")) .collect() # declenche l'execution optimisee ) # Polars optimise automatiquement : predicate pushdown, # projection pushdown, parallelisme multi-thread natif

6Profiling et diagnostic de performance

Question discriminante

Comment identifiez-vous le goulot d'etranglement dans un script Python data lent ?

import cProfile import timeit # cProfile : profiling par fonction cProfile.run('process_dataframe(df)', sort='cumulative') # timeit : comparer deux approches t1 = timeit.timeit( 'df.groupby("category").agg({"amount": "sum"})', globals=globals(), number=100 ) # memory_profiler : profiling memoire ligne par ligne from memory_profiler import profile @profile def process_data(df): result = df.groupby('category').agg({'amount': 'sum'}) return result # YData Profiling : rapport qualite automatique from ydata_profiling import ProfileReport report = ProfileReport(df, title="Data Quality Report") report.to_file("report.html")

7Grille par niveau

NiveauMaitrise attendueSignal GONO-GO
Juniorpandas basique, vectorisation, groupby/merge/pivotEvite iterrows(), utilise .loc correctement, sait faire un merge multi-clesUtilise des boucles for sur les DataFrames, ne sait pas ce qu'est la vectorisation
ConfirmeOptimisation memoire, DuckDB, profiling, types CategoryReduit la memoire via les dtypes, a utilise DuckDB sur un projet, sait utiliser cProfileNe connait pas DuckDB, ne sait pas reduire la consommation memoire
SeniorPolars, streaming gros volumes, benchmarks, tests de perfA utilise Polars sur un projet reel, traite des fichiers plus grands que la RAM avec DuckDB ou chunksN'a jamais entendu parler de Polars, ne sait pas traiter un fichier plus grand que la RAM
LeadArchitecture data locale vs distribuee, choix Spark vs DuckDB vs Polars selon le contexteJustifie le choix DuckDB vs Spark selon le volume et le contexte, a defini les standards Python de son equipeNe peut pas expliquer quand utiliser Spark plutot que DuckDB

Vous recrutez un Data Engineer ou Data Scientist Python ?

Premier entretien gratuit. Rapport GO/NO-GO sous 48h.