Lire un CSV par flux avec chunksize
Lisez un CSV volumineux par blocs de taille fixe avec pd.read_csv(chunksize=), traitez chaque bloc, puis concaténez ou accumulez les résultats.
Lire un CSV par flux avec chunksize est une leçon Pandas & NumPy Academy gratuite sur CoddyKit. Ceci est la leçon 1 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.
Le problème des fichiers CSV volumineux
Lorsqu’un fichier CSV est plus volumineux que la RAM disponible — par exemple un fichier journal de 50 GB sur une machine disposant de 16 GB de mémoire — l’appel à pd.read_csv('file.csv') échoue avec une MemoryError ou force le système à utiliser intensivement la mémoire virtuelle, ce qui le rend extrêmement lent. La solution consiste à effectuer une lecture par blocs : au lieu de charger tout le fichier en une seule fois, vous le traitez par morceaux de taille fixe et accumulez les résultats sans jamais conserver simultanément toutes les données en mémoire.
Le paramètre chunksize de read_csv
Le passage de chunksize=N à pd.read_csv() renvoie un itérateur TextFileReader plutôt qu’un DataFrame. Chaque itération produit un DataFrame contenant au maximum N lignes. Le fichier est lu de manière différée : aucune donnée n’est chargée tant que vous ne demandez pas le bloc suivant. Cet itérateur peut être utilisé dans une boucle for ou transmis à pd.concat(). Choisissez une valeur de chunksize suffisamment grande pour garantir des entrées-sorties efficaces (par exemple, 10 000 à 100 000 lignes), mais assez petite pour tenir confortablement en mémoire.
import pandas as pd
# Returns a TextFileReader iterator, NOT a DataFrame
chunks = pd.read_csv('sales_data.csv', chunksize=10000)
print(type(chunks)) # <class 'pandas.io.parsers.readers.TextFileReader'>
for chunk in chunks:
print(f'Chunk shape: {chunk.shape}')
# process each chunk independently
break # just show the first chunk hereTraiter chaque bloc indépendamment
Le schéma le plus courant consiste à effectuer une transformation ou un filtrage sur chaque bloc, à recueillir les résultats dans une liste, puis à les concaténer. Vous pouvez par exemple filtrer les lignes correspondant à une condition, calculer des statistiques pour chaque bloc ou sélectionner uniquement les colonnes nécessaires. Le travail sur des sous-ensembles signifie que seul le bloc courant occupe de la mémoire, tandis que le reste du fichier n’est pas modifié. Après la boucle, un unique pd.concat(results) assemble le DataFrame final.
import pandas as pd
results = []
for chunk in pd.read_csv('orders.csv', chunksize=50000):
# Keep only high-value orders
filtered = chunk[chunk['amount'] > 1000]
results.append(filtered)
# Combine all filtered chunks
high_value = pd.concat(results, ignore_index=True)
print('High-value orders:', len(high_value))Accumuler des agrégats entre les blocs
Parfois, vous n’avez besoin de conserver aucune ligne : vous avez seulement besoin d’un agrégat cumulatif. Suivez une somme, un décompte ou un min/max cumulatif entre les blocs sans constituer une liste de DataFrames. Il s’agit du schéma le plus économe en mémoire, car l’utilisation de la mémoire reste constante quelle que soit la taille du fichier. À la fin, calculez la statistique finale à partir de vos accumulateurs.
import pandas as pd
total_revenue = 0.0
total_rows = 0
for chunk in pd.read_csv('sales.csv', chunksize=100000):
total_revenue += chunk['revenue'].sum()
total_rows += len(chunk)
print(f'Processed {total_rows:,} rows')
print(f'Total revenue: ${total_revenue:,.2f}')Spécifier le type de données pour accélérer la lecture par blocs
Par défaut, Pandas déduit les types de données des colonnes à partir des données, ce qui nécessite d’analyser chaque bloc deux fois (une fois pour la déduction, une fois pour l’analyse). Fournir l’argument type de données évite cette surcharge et empêche également les incohérences de type entre les blocs. Par exemple, une colonne contenant principalement des entiers mais aussi une cellule vide peut être interprétée comme float64 dans un bloc et comme object dans un autre. La spécification explicite des types de données garantit une lecture cohérente et plus rapide de tous les blocs.
import pandas as pd
dtype_map = {
'order_id': 'int32',
'customer_id': 'int32',
'amount': 'float32',
'category': 'category'
}
for chunk in pd.read_csv('orders.csv',
chunksize=50000,
dtype=dtype_map,
parse_dates=['order_date']):
print(chunk.dtypes)
breakSélectionner uniquement les colonnes nécessaires
Utilisez le paramètre usecols pour charger uniquement les colonnes dont votre analyse a besoin. Si un CSV contient 50 colonnes mais que votre agrégation n’en utilise que 3, il n’est pas nécessaire d’analyser les 47 autres. La combinaison de usecols et de chunksize réduit considérablement le temps d’entrée-sortie et l’utilisation de la mémoire. Il s’agit de l’une des optimisations les plus simples et les plus efficaces pour le traitement de fichiers CSV volumineux.
import pandas as pd
# Only read the three columns we actually need
for chunk in pd.read_csv(
'large_transactions.csv',
chunksize=100000,
usecols=['date', 'amount', 'region']
):
print(chunk.columns.tolist())
print(chunk.memory_usage(deep=True).sum() / 1e6, 'MB per chunk')
breakAgrégation GroupBy par blocs
Effectuer une agrégation groupby sur plusieurs blocs nécessite d’accumuler des résultats partiels. Calculez le groupby dans chaque bloc, puis combinez les résultats à l’aide d’un second groupby sur les résultats partiels concaténés. Par exemple, pour obtenir le total des ventes par région dans un fichier de 10 GB, recueillez les sommes par région de chaque bloc dans une liste, puis concaténez-les et effectuez à nouveau un groupby. Ce schéma d’agrégation en deux passes est parfois appelé une approche map-reduce.
import pandas as pd
partials = []
for chunk in pd.read_csv('sales.csv',
chunksize=100000,
usecols=['region', 'revenue']):
partial = chunk.groupby('region')['revenue'].sum()
partials.append(partial)
# Combine partial sums
final = pd.concat(partials).groupby(level=0).sum()
print('Revenue by region:')
print(final.sort_values(ascending=False))Gérer les erreurs d’analyse entre les blocs
Les fichiers CSV volumineux provenant de sources externes contiennent souvent des lignes mal formées — virgules supplémentaires, encodage incorrect ou lignes tronquées. Utilisez on_bad_lines='skip' (Pandas 1.3 et versions ultérieures) ou error_bad_lines=False (anciennes versions de Pandas) pour ignorer silencieusement les lignes incorrectes, et encoding='latin-1' si l’analyse en UTF-8 échoue. Suivez les blocs qui ont produit des erreurs en entourant le traitement de chaque bloc d’un bloc try-except, afin de construire un pipeline robuste qui ne s’interrompt pas à cause d’une seule ligne incorrecte dans un fichier de 10 millions de lignes.
import pandas as pd
bad_chunks = []
all_chunks = []
for i, chunk in enumerate(pd.read_csv(
'raw_data.csv',
chunksize=50000,
on_bad_lines='skip',
encoding='utf-8',
encoding_errors='replace'
)):
try:
# Your transformation here
all_chunks.append(chunk)
except Exception as e:
bad_chunks.append((i, str(e)))
print(f'Chunk {i} error: {e}')
print(f'Processed {len(all_chunks)} chunks, {len(bad_chunks)} errors')Écrire les résultats par blocs dans les fichiers de sortie
Lorsque les résultats traités sont eux aussi volumineux, écrivez-les progressivement au lieu de tout accumuler en mémoire pour les écrire à la fin. Ouvrez un fichier CSV et ajoutez chaque bloc traité en utilisant mode='a' et header=False pour les blocs suivants. La mémoire utilisée par le pipeline de sortie reste ainsi constante et vous pouvez examiner les résultats partiels avant la fin de l’exécution complète.
import pandas as pd
first_chunk = True
for chunk in pd.read_csv('input.csv', chunksize=100000):
# Transform
processed = chunk[chunk['status'] == 'active'].copy()
processed['revenue_usd'] = processed['revenue'] * 1.10
# Write incrementally
mode = 'w' if first_chunk else 'a'
processed.to_csv('output.csv',
mode=mode,
header=first_chunk,
index=False)
first_chunk = False
print('Done writing output.csv')Estimer la taille optimale des blocs
Le choix de chunksize est un compromis : une valeur trop faible entraîne de nombreuses itérations de boucle Python et une surcharge importante ; une valeur trop élevée produit des blocs qui ne tiennent pas dans la RAM. Une approche pratique consiste à charger un bloc, à mesurer sa mémoire avec chunk.memory_usage(deep=True).sum(), puis à définir chunksize de sorte que chaque bloc utilise environ 10 à 20 % de la RAM disponible. psutil.virtual_memory().available de Python fournit la RAM disponible lors de l’exécution, ce qui permet de calculer une valeur de chunksize adaptative.
import pandas as pd
# Sample 1000 rows to estimate per-row memory
sample = pd.read_csv('big_file.csv', nrows=1000)
bytes_per_row = sample.memory_usage(deep=True).sum() / 1000
print(f'Bytes per row: {bytes_per_row:.0f}')
# Target: use at most 500 MB per chunk
target_bytes = 500 * 1024 * 1024
optimal_chunksize = int(target_bytes / bytes_per_row)
print(f'Recommended chunksize: {optimal_chunksize:,}')Combiner efficacement les résultats par blocs
Lorsque vous accumulez de nombreux DataFrames correspondant aux blocs dans une liste avant de les concaténer, sachez que l’appel à pd.concat sur des centaines de petits DataFrames est lent en raison des allocations répétées de mémoire. Une meilleure approche consiste à agréger chaque bloc et à ne stocker que le petit résultat agrégé, plutôt que le bloc complet. Si vous avez réellement besoin de toutes les lignes, écrire progressivement dans un fichier Parquet (avec pyarrow) est plus rapide que d’utiliser pd.concat à la fin.
import pandas as pd
# Efficient: aggregate first, small list of scalars
running_total = 0
running_count = 0
for chunk in pd.read_csv('sales.csv', chunksize=100000):
running_total += chunk['amount'].sum()
running_count += chunk['amount'].count()
print(f'Mean amount: {running_total / running_count:.2f}')
# Avoid: accumulating full chunk DataFrames
# results = []
# for chunk in reader:
# results.append(chunk) # memory grows to full file size
# df = pd.concat(results) # slow for hundreds of chunksVérification rapide
Testez votre compréhension des concepts d’analyse de données présentés dans cette leçon.
Récapitulatif de la leçon
Dans cette leçon, vous avez appris que chunksize dans pd.read_csv renvoie un itérateur de DataFrames permettant de traiter efficacement les fichiers volumineux en mémoire, que les arguments usecols et type de données réduisent la mémoire utilisée pour chaque bloc et accélèrent l’analyse, et que les accumulateurs cumulatifs (sum, count, résultats partiels) évitent de constituer une liste contenant tous les blocs. Nous allons maintenant étudier plus en détail les schémas d’agrégation progressive entre les blocs.
Questions Fréquemment Posées
La leçon « Lire un CSV par flux avec chunksize » est-elle gratuite ?
Oui — le texte complet de « Lire un CSV par flux avec chunksize » 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 « Lire un CSV par flux avec chunksize » ?
Lisez un CSV volumineux par blocs de taille fixe avec pd.read_csv(chunksize=), traitez chaque bloc, puis concaténez ou accumulez les résultats. 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 1 sur 4.
Combien de temps prend la leçon « Lire un CSV par flux avec chunksize » ?
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
- Lire un CSV par flux avec chunksize
- Agrégation progressive entre les blocs
- Introduction aux DataFrames Dask
- Parquet : stockage colonnaire rapide