Introduction
La manipulation de fichiers CSV volumineux est un défi courant pour les développeurs Python. Ce tutoriel vous guide à travers des techniques efficaces pour traiter ces fichiers de manière performante, en mettant l'accent sur l'optimisation des performances et l'utilisation de la mémoire. À la fin de ce lab, vous serez équipé des connaissances pratiques nécessaires pour aborder les tâches de traitement de fichiers CSV gourmandes en données en Python.
Que vous analysiez des données clients, traitiez des enregistrements financiers ou travailliez avec tout type de données structurées, les compétences acquises dans ce lab vous aideront à traiter efficacement de grands ensembles de données sans rencontrer de problèmes de mémoire.
Création et lecture d'un fichier CSV simple
CSV (Comma-Separated Values) est un format de fichier populaire utilisé pour stocker des données tabulaires. Dans cette étape, nous allons créer un fichier CSV simple et apprendre à le lire en utilisant le module csv intégré de Python.
Comprendre les fichiers CSV
Un fichier CSV stocke les données dans un format texte brut où :
- Chaque ligne représente une ligne de données
- Les valeurs de chaque ligne sont séparées par un délimiteur (généralement une virgule)
- La première ligne contient souvent les en-têtes de colonnes
Commençons par créer un fichier CSV simple avec lequel travailler.
Création d'un fichier CSV
Tout d'abord, créons un répertoire dans lequel travailler, puis créons un fichier CSV simple :
- Ouvrez le terminal dans le WebIDE
- Créez un nouveau fichier Python nommé
csv_basics.pydans l'éditeur
Maintenant, ajoutez le code suivant à csv_basics.py :
import csv
## Data to write to CSV
data = [
['Name', 'Age', 'City'], ## Header row
['John Smith', '28', 'New York'],
['Sarah Johnson', '32', 'San Francisco'],
['Michael Brown', '45', 'Chicago'],
['Emily Davis', '36', 'Boston'],
['David Wilson', '52', 'Seattle']
]
## Writing data to a CSV file
with open('sample_data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerows(data)
print("CSV file 'sample_data.csv' created successfully.")
Exécutez ce code en exécutant la commande suivante dans le terminal :
python3 csv_basics.py
Sortie attendue :
CSV file 'sample_data.csv' created successfully.
Cela créera un nouveau fichier CSV nommé sample_data.csv dans votre répertoire actuel. Vous pouvez afficher le contenu de ce fichier en exécutant :
cat sample_data.csv
Sortie attendue :
Name,Age,City
John Smith,28,New York
Sarah Johnson,32,San Francisco
Michael Brown,45,Chicago
Emily Davis,36,Boston
David Wilson,52,Seattle
Lecture d'un fichier CSV
Maintenant, lisons le fichier CSV que nous venons de créer. Créez un nouveau fichier nommé read_csv.py avec le code suivant :
import csv
## Reading a CSV file
with open('sample_data.csv', 'r') as file:
reader = csv.reader(file)
print("Contents of sample_data.csv:")
print("--------------------------")
for row in reader:
print(row)
## Reading and accessing specific columns
print("\nReading specific columns:")
print("--------------------------")
with open('sample_data.csv', 'r') as file:
reader = csv.reader(file)
headers = next(reader) ## Skip the header row
for row in reader:
name = row[0]
age = row[1]
city = row[2]
print(f"Name: {name}, Age: {age}, City: {city}")
Exécutez ce code avec :
python3 read_csv.py
Sortie attendue :
Contents of sample_data.csv:
--------------------------
['Name', 'Age', 'City']
['John Smith', '28', 'New York']
['Sarah Johnson', '32', 'San Francisco']
['Michael Brown', '45', 'Chicago']
['Emily Davis', '36', 'Boston']
['David Wilson', '52', 'Seattle']
Reading specific columns:
--------------------------
Name: John Smith, Age: 28, City: New York
Name: Sarah Johnson, Age: 32, City: San Francisco
Name: Michael Brown, Age: 45, City: Chicago
Name: Emily Davis, Age: 36, City: Boston
Name: David Wilson, Age: 52, City: Seattle
Comprendre le module CSV
Le module csv de Python fournit deux classes principales :
csv.reader: Lit les fichiers CSV et renvoie chaque ligne sous forme de liste de chaînes de caractèrescsv.writer: Écrit des données dans des fichiers CSV
Ce module gère toutes les complexités liées à la gestion de différents formats CSV, tels que l'échappement des caractères spéciaux et la gestion des guillemets.
Dans cette étape, vous avez appris à créer et à lire un fichier CSV simple. Dans l'étape suivante, nous explorerons des moyens plus efficaces de gérer des fichiers CSV plus volumineux.
Utilisation de DictReader pour un traitement CSV pratique
Dans l'étape précédente, nous avons travaillé avec les fonctions de base csv.reader et csv.writer. Maintenant, explorons une manière plus pratique de traiter les fichiers CSV en utilisant la classe csv.DictReader, ce qui est particulièrement utile lorsque l'on travaille avec des données qui ont des en-têtes de colonnes.
Qu'est-ce que DictReader ?
csv.DictReader lit les fichiers CSV et renvoie chaque ligne sous forme de dictionnaire où :
- Les clés sont tirées des en-têtes de colonnes (première ligne du fichier CSV par défaut)
- Les valeurs sont les données correspondantes de chaque ligne
Cette approche rend votre code plus lisible et moins sujet aux erreurs, car vous pouvez référencer les colonnes par nom au lieu de par index.
Créer un fichier de test plus grand
Tout d'abord, créons un fichier CSV légèrement plus grand pour démontrer les avantages de DictReader. Créez un nouveau fichier nommé create_users_data.py avec le code suivant :
import csv
import random
## Generate some sample user data
def generate_users(count):
users = [['id', 'name', 'email', 'age', 'country']] ## Header row
domains = ['gmail.com', 'yahoo.com', 'outlook.com', 'example.com']
countries = ['USA', 'Canada', 'UK', 'Australia', 'Germany', 'France', 'Japan', 'Brazil']
first_names = ['John', 'Jane', 'Michael', 'Emily', 'David', 'Sarah', 'Robert', 'Lisa']
last_names = ['Smith', 'Johnson', 'Brown', 'Davis', 'Wilson', 'Miller', 'Jones', 'Taylor']
for i in range(1, count + 1):
first_name = random.choice(first_names)
last_name = random.choice(last_names)
name = f"{first_name} {last_name}"
email = f"{first_name.lower()}.{last_name.lower()}@{random.choice(domains)}"
age = random.randint(18, 65)
country = random.choice(countries)
users.append([str(i), name, email, str(age), country])
return users
## Create a CSV file with 100 users
users_data = generate_users(100)
## Write data to CSV file
with open('users_data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerows(users_data)
print(f"Created 'users_data.csv' with 100 user records")
Exécutez le script pour créer le fichier :
python3 create_users_data.py
Sortie attendue :
Created 'users_data.csv' with 100 user records
Examinons les premières lignes de ce nouveau fichier :
head -n 5 users_data.csv
Vous devriez voir la ligne d'en-tête suivie de 4 lignes de données :
id,name,email,age,country
1,John Smith,john.smith@gmail.com,25,USA
2,Emily Brown,emily.brown@yahoo.com,32,Canada
3,David Jones,david.jones@outlook.com,45,UK
4,Sarah Wilson,sarah.wilson@example.com,28,Australia
Utilisation de DictReader pour traiter le fichier CSV
Maintenant, créons un script pour traiter ce fichier en utilisant DictReader. Créez un nouveau fichier nommé dict_reader_example.py avec le code suivant :
import csv
## Read the CSV file using DictReader
with open('users_data.csv', 'r') as file:
csv_reader = csv.DictReader(file)
## Print the field names (column headers)
print(f"Column headers: {csv_reader.fieldnames}")
print("\nFirst 5 records:")
print("-----------------")
## Print the first 5 records
for i, row in enumerate(csv_reader):
if i < 5:
## Access fields by name
print(f"User {row['id']}: {row['name']}, {row['age']} years old, from {row['country']}")
print(f" Email: {row['email']}")
else:
break
## Using DictReader for data analysis
with open('users_data.csv', 'r') as file:
csv_reader = csv.DictReader(file)
## Calculate average age
total_age = 0
user_count = 0
## Count users by country
countries = {}
for row in csv_reader:
user_count += 1
total_age += int(row['age'])
## Count users by country
country = row['country']
if country in countries:
countries[country] += 1
else:
countries[country] = 1
avg_age = total_age / user_count if user_count > 0 else 0
print("\nData Analysis:")
print("--------------")
print(f"Total users: {user_count}")
print(f"Average age: {avg_age:.2f} years")
print("\nUsers by country:")
for country, count in sorted(countries.items(), key=lambda x: x[1], reverse=True):
print(f" {country}: {count} users")
Exécutez ce script :
python3 dict_reader_example.py
Sortie attendue (vos valeurs exactes peuvent varier car les données sont générées aléatoirement) :
Column headers: ['id', 'name', 'email', 'age', 'country']
First 5 records:
-----------------
User 1: John Smith, 25 years old, from USA
Email: john.smith@gmail.com
User 2: Emily Brown, 32 years old, from Canada
Email: emily.brown@yahoo.com
User 3: David Jones, 45 years old, from UK
Email: david.jones@outlook.com
User 4: Sarah Wilson, 28 years old, from Australia
Email: sarah.wilson@example.com
User 5: Michael Taylor, 37 years old, from Germany
Email: michael.taylor@example.com
Data Analysis:
--------------
Total users: 100
Average age: 41.35 years
Users by country:
USA: 16 users
Canada: 14 users
Japan: 13 users
UK: 12 users
Germany: 12 users
Australia: 12 users
France: 11 users
Brazil: 10 users
Avantages de l'utilisation de DictReader
Comme vous pouvez le constater, l'utilisation de DictReader offre plusieurs avantages :
- Code lisible : Vous pouvez accéder aux champs par nom au lieu de mémoriser les positions d'index
- Auto-documenté : Le code montre clairement à quel champ vous accédez
- Flexibilité : Si l'ordre des colonnes change dans le fichier CSV, votre code fonctionne toujours tant que les noms des colonnes restent les mêmes
Cette approche est particulièrement utile lorsque vous travaillez avec des données réelles qui comportent de nombreuses colonnes ou lorsque l'ordre des colonnes peut changer au fil du temps.
Dans l'étape suivante, nous explorerons des techniques efficaces pour traiter des fichiers CSV plus volumineux sans tout charger en mémoire à la fois.
Traitement efficace des fichiers CSV volumineux
Dans des scénarios réels, vous devrez peut-être traiter des fichiers CSV de plusieurs gigaoctets. Le chargement de ces fichiers entièrement en mémoire peut entraîner le plantage de votre application ou un ralentissement important. Dans cette étape, nous allons explorer des techniques pour traiter efficacement les fichiers CSV volumineux.
Le défi de la mémoire avec les fichiers volumineux
Lorsque vous travaillez avec des fichiers CSV, il existe trois approches courantes, chacune ayant des exigences de mémoire différentes :
- Chargement de l'intégralité du fichier en mémoire - Simple mais utilise le plus de mémoire
- Streaming du fichier ligne par ligne - Utilise un minimum de mémoire mais peut être plus lent pour les opérations complexes
- Chunking (traitement par blocs) - Un entre-deux qui traite le fichier par blocs gérables
Explorons chacune de ces approches avec des exemples pratiques.
Création d'un fichier d'exemple plus grand
Tout d'abord, créons un fichier d'exemple plus grand pour démontrer ces techniques. Créez un nouveau fichier nommé create_large_csv.py :
import csv
import random
from datetime import datetime, timedelta
def create_large_csv(filename, num_rows):
## Define column headers
headers = ['transaction_id', 'date', 'customer_id', 'product_id', 'amount', 'status']
## Create a file with the specified number of rows
with open(filename, 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(headers)
## Generate random data
start_date = datetime(2022, 1, 1)
status_options = ['completed', 'pending', 'failed', 'refunded']
for i in range(1, num_rows + 1):
## Generate random values
transaction_id = f"TXN-{i:08d}"
days_offset = random.randint(0, 365)
date = (start_date + timedelta(days=days_offset)).strftime('%Y-%m-%d')
customer_id = f"CUST-{random.randint(1001, 9999)}"
product_id = f"PROD-{random.randint(101, 999)}"
amount = round(random.uniform(10.0, 500.0), 2)
status = random.choice(status_options)
## Write row to CSV
writer.writerow([transaction_id, date, customer_id, product_id, amount, status])
## Print progress indicator for every 10,000 rows
if i % 10000 == 0:
print(f"Generated {i} rows...")
## Create a CSV file with 50,000 rows (about 5-10 MB)
create_large_csv('transactions.csv', 50000)
print("Large CSV file 'transactions.csv' has been created.")
Exécutez ce script pour créer le fichier :
python3 create_large_csv.py
Sortie attendue :
Generated 10000 rows...
Generated 20000 rows...
Generated 30000 rows...
Generated 40000 rows...
Generated 50000 rows...
Large CSV file 'transactions.csv' has been created.
Vous pouvez vérifier la taille du fichier avec :
ls -lh transactions.csv
Sortie attendue (la taille peut varier légèrement) :
-rw-r--r-- 1 labex labex 3.8M Apr 15 12:30 transactions.csv
Approche 1 : Traitement ligne par ligne (Streaming)
L'approche la plus économe en mémoire consiste à traiter un fichier CSV ligne par ligne. Créez un fichier nommé streaming_example.py :
import csv
import time
def process_csv_streaming(filename):
print(f"Processing {filename} using streaming (line by line)...")
start_time = time.time()
## Track some statistics
row_count = 0
total_amount = 0
status_counts = {'completed': 0, 'pending': 0, 'failed': 0, 'refunded': 0}
## Process the file line by line
with open(filename, 'r') as file:
reader = csv.DictReader(file)
for row in reader:
## Increment row counter
row_count += 1
## Process row data
amount = float(row['amount'])
status = row['status']
## Update statistics
total_amount += amount
status_counts[status] += 1
## Calculate and display results
end_time = time.time()
processing_time = end_time - start_time
print(f"\nResults:")
print(f"Processed {row_count:,} rows in {processing_time:.2f} seconds")
print(f"Total transaction amount: ${total_amount:,.2f}")
print(f"Average transaction amount: ${total_amount/row_count:.2f}")
print("\nTransaction status breakdown:")
for status, count in status_counts.items():
percentage = (count / row_count) * 100
print(f" {status}: {count:,} ({percentage:.1f}%)")
## Process the file
process_csv_streaming('transactions.csv')
Exécutez ce script :
python3 streaming_example.py
Sortie attendue (vos chiffres exacts peuvent varier) :
Processing transactions.csv using streaming (line by line)...
Results:
Processed 50,000 rows in 0.17 seconds
Total transaction amount: $12,739,853.35
Average transaction amount: $254.80
Transaction status breakdown:
completed: 12,432 (24.9%)
pending: 12,598 (25.2%)
failed: 12,414 (24.8%)
refunded: 12,556 (25.1%)
Approche 2 : Traitement par blocs (Chunked Processing)
Pour des opérations plus complexes ou lorsque vous devez traiter les données par lots, vous pouvez utiliser une approche par blocs. Créez un fichier nommé chunked_example.py :
import csv
import time
def process_csv_chunked(filename, chunk_size=10000):
print(f"Processing {filename} using chunks of {chunk_size} rows...")
start_time = time.time()
## Track some statistics
row_count = 0
total_amount = 0
status_counts = {'completed': 0, 'pending': 0, 'failed': 0, 'refunded': 0}
## Process the file in chunks
with open(filename, 'r') as file:
reader = csv.DictReader(file)
chunk = []
for row in reader:
## Add row to current chunk
chunk.append(row)
## When chunk reaches desired size, process it
if len(chunk) >= chunk_size:
## Process the chunk
for row_data in chunk:
## Update statistics
row_count += 1
amount = float(row_data['amount'])
status = row_data['status']
total_amount += amount
status_counts[status] += 1
print(f"Processed chunk of {len(chunk)} rows... ({row_count:,} total)")
## Clear the chunk for next batch
chunk = []
## Process any remaining rows in the last chunk
if chunk:
for row_data in chunk:
row_count += 1
amount = float(row_data['amount'])
status = row_data['status']
total_amount += amount
status_counts[status] += 1
print(f"Processed final chunk of {len(chunk)} rows... ({row_count:,} total)")
## Calculate and display results
end_time = time.time()
processing_time = end_time - start_time
print(f"\nResults:")
print(f"Processed {row_count:,} rows in {processing_time:.2f} seconds")
print(f"Total transaction amount: ${total_amount:,.2f}")
print(f"Average transaction amount: ${total_amount/row_count:.2f}")
print("\nTransaction status breakdown:")
for status, count in status_counts.items():
percentage = (count / row_count) * 100
print(f" {status}: {count:,} ({percentage:.1f}%)")
## Process the file with chunks of 10,000 rows
process_csv_chunked('transactions.csv', chunk_size=10000)
Exécutez ce script :
python3 chunked_example.py
Sortie attendue :
Processing transactions.csv using chunks of 10000 rows...
Processed chunk of 10000 rows... (10,000 total)
Processed chunk of 10000 rows... (20,000 total)
Processed chunk of 10000 rows... (30,000 total)
Processed chunk of 10000 rows... (40,000 total)
Processed chunk of 10000 rows... (50,000 total)
Results:
Processed 50,000 rows in 0.20 seconds
Total transaction amount: $12,739,853.35
Average transaction amount: $254.80
Transaction status breakdown:
completed: 12,432 (24.9%)
pending: 12,598 (25.2%)
failed: 12,414 (24.8%)
refunded: 12,556 (25.1%)
Comparaison de l'utilisation de la mémoire
Les principales différences entre ces approches sont les suivantes :
Streaming (ligne par ligne) :
- Utilise un minimum de mémoire quelle que soit la taille du fichier
- Idéal pour les très grands fichiers
- Opérations simples sur chaque ligne
Traitement par blocs :
- Utilise plus de mémoire que le streaming, mais reste efficace
- Bon pour les opérations qui doivent traiter les lignes par lots
- Fournit des mises à jour de progression pendant le traitement
- Peut être combiné avec le traitement en parallèle (multiprocessing)
Dans la plupart des cas pratiques, l'approche de streaming est recommandée, sauf si vous avez spécifiquement besoin de capacités de traitement par lots. Elle offre la meilleure efficacité mémoire tout en maintenant de bonnes performances.
Dans l'étape suivante, nous explorerons l'utilisation de bibliothèques tierces comme pandas pour des capacités de traitement CSV encore plus puissantes.
Utilisation de Pandas pour le traitement CSV avancé
Bien que le module csv intégré de Python soit puissant, la bibliothèque pandas offre des fonctionnalités plus avancées pour l'analyse et la manipulation des données. Dans cette étape, nous allons explorer comment utiliser pandas pour un traitement CSV efficace.
Installation de Pandas
Tout d'abord, installons la bibliothèque pandas :
pip install pandas
Sortie attendue :
Collecting pandas
Downloading pandas-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.3/12.3 MB 42.6 MB/s eta 0:00:00
...
Successfully installed pandas-2.0.0 numpy-1.24.3 python-dateutil-2.8.2 pytz-2023.3 tzdata-2023.3
Lecture de fichiers CSV avec Pandas
Pandas facilite la lecture, l'analyse et la manipulation des données CSV. Créez un fichier nommé pandas_basic.py :
import pandas as pd
import time
def process_with_pandas(filename):
print(f"Processing {filename} with pandas...")
start_time = time.time()
## Read the CSV file into a DataFrame
df = pd.read_csv(filename)
## Display basic information
print(f"\nDataFrame Info:")
print(f"Shape: {df.shape} (rows, columns)")
print(f"Column names: {', '.join(df.columns)}")
## Display the first 5 rows
print("\nFirst 5 rows:")
print(df.head())
## Basic statistics
print("\nSummary statistics for numeric columns:")
print(df.describe())
## Group by analysis
print("\nTransaction counts by status:")
status_counts = df['status'].value_counts()
print(status_counts)
## Calculate average amount by status
print("\nAverage transaction amount by status:")
avg_by_status = df.groupby('status')['amount'].mean()
print(avg_by_status)
## Calculate total amount by date (first 5 dates)
print("\nTotal transaction amount by date (first 5 dates):")
total_by_date = df.groupby('date')['amount'].sum().sort_values(ascending=False).head(5)
print(total_by_date)
end_time = time.time()
print(f"\nProcessed in {end_time - start_time:.2f} seconds")
## Process the transactions file
process_with_pandas('transactions.csv')
Exécutez ce script :
python3 pandas_basic.py
Sortie attendue (tronquée pour plus de brièveté) :
Processing transactions.csv with pandas...
DataFrame Info:
Shape: (50000, 6) (rows, columns)
Column names: transaction_id, date, customer_id, product_id, amount, status
First 5 rows:
transaction_id date customer_id product_id amount status
0 TXN-00000001 2022-12-19 CUST-5421 PROD-383 385.75 refunded
1 TXN-00000002 2022-02-01 CUST-7078 PROD-442 286.83 completed
2 TXN-00000003 2022-12-24 CUST-2356 PROD-701 364.87 failed
3 TXN-00000004 2022-04-09 CUST-3458 PROD-854 247.73 pending
4 TXN-00000005 2022-03-07 CUST-6977 PROD-307 298.69 completed
Summary statistics for numeric columns:
amount
count 50000.000000
mean 254.797067
std 141.389125
min 10.010000
25% 127.732500
50% 254.865000
75% 381.387500
max 499.990000
Transaction counts by status:
pending 12598
refunded 12556
completed 12432
failed 12414
Name: status, dtype: int64
Average transaction amount by status:
status
completed 255.028733
failed 254.709444
pending 254.690785
refunded 254.760390
Name: amount, dtype: float64
Total transaction amount by date (first 5 dates):
date
2022-01-20 38883.19
2022-08-30 38542.49
2022-03-10 38331.67
2022-11-29 38103.61
2022-06-24 37954.87
Name: amount, dtype: float64
Processed in 0.11 seconds
Traitement de fichiers CSV volumineux avec Pandas
Bien que pandas soit puissant, il peut consommer beaucoup de mémoire lors du chargement de fichiers CSV volumineux. Pour les très grands fichiers, vous pouvez utiliser le paramètre chunksize pour lire le fichier par blocs. Créez un fichier nommé pandas_chunked.py :
import pandas as pd
import time
def process_large_csv_with_pandas(filename, chunk_size=10000):
print(f"Processing {filename} with pandas using chunks of {chunk_size} rows...")
start_time = time.time()
## Initialize variables to store aggregated results
total_rows = 0
total_amount = 0
status_counts = {'completed': 0, 'pending': 0, 'failed': 0, 'refunded': 0}
daily_totals = {}
## Process the file in chunks
for chunk_num, chunk in enumerate(pd.read_csv(filename, chunksize=chunk_size)):
## Update row count
chunk_rows = len(chunk)
total_rows += chunk_rows
## Update total amount
chunk_amount = chunk['amount'].sum()
total_amount += chunk_amount
## Update status counts
for status, count in chunk['status'].value_counts().items():
status_counts[status] += count
## Update daily totals
for date, group in chunk.groupby('date'):
if date in daily_totals:
daily_totals[date] += group['amount'].sum()
else:
daily_totals[date] = group['amount'].sum()
print(f"Processed chunk {chunk_num + 1} ({total_rows:,} rows so far)")
## Calculate results
end_time = time.time()
processing_time = end_time - start_time
print(f"\nResults after processing {total_rows:,} rows in {processing_time:.2f} seconds:")
print(f"Total transaction amount: ${total_amount:,.2f}")
print(f"Average transaction amount: ${total_amount/total_rows:.2f}")
print("\nTransaction status breakdown:")
for status, count in status_counts.items():
percentage = (count / total_rows) * 100
print(f" {status}: {count:,} ({percentage:.1f}%)")
## Show top 5 days by transaction amount
print("\nTop 5 days by transaction amount:")
top_days = sorted(daily_totals.items(), key=lambda x: x[1], reverse=True)[:5]
for date, amount in top_days:
print(f" {date}: ${amount:,.2f}")
## Process the transactions file with chunks
process_large_csv_with_pandas('transactions.csv', chunk_size=10000)
Exécutez ce script :
python3 pandas_chunked.py
Sortie attendue :
Processing transactions.csv with pandas using chunks of 10000 rows...
Processed chunk 1 (10,000 rows so far)
Processed chunk 2 (20,000 rows so far)
Processed chunk 3 (30,000 rows so far)
Processed chunk 4 (40,000 rows so far)
Processed chunk 5 (50,000 rows so far)
Results after processing 50,000 rows in 0.34 seconds:
Total transaction amount: $12,739,853.35
Average transaction amount: $254.80
Transaction status breakdown:
completed: 12,432 (24.9%)
pending: 12,598 (25.2%)
failed: 12,414 (24.8%)
refunded: 12,556 (25.1%)
Top 5 days by transaction amount:
2022-01-20: $38,883.19
2022-08-30: $38,542.49
2022-03-10: $38,331.67
2022-11-29: $38,103.61
2022-06-24: $37,954.87
Filtrage et transformation des données avec Pandas
L'un des grands avantages de pandas est la possibilité de filtrer et de transformer facilement les données. Créez un fichier nommé pandas_filter.py :
import pandas as pd
import time
def filter_and_transform(filename):
print(f"Filtering and transforming data from {filename}...")
start_time = time.time()
## Read the CSV file
df = pd.read_csv(filename)
## 1. Filter: Get only completed transactions
completed = df[df['status'] == 'completed']
print(f"Number of completed transactions: {len(completed)}")
## 2. Filter: Get high-value transactions (over $400)
high_value = df[df['amount'] > 400]
print(f"Number of high-value transactions (>${400}): {len(high_value)}")
## 3. Filter: Transactions from first quarter of 2022
df['date'] = pd.to_datetime(df['date']) ## Convert to datetime
q1_2022 = df[(df['date'] >= '2022-01-01') & (df['date'] <= '2022-03-31')]
print(f"Number of transactions in Q1 2022: {len(q1_2022)}")
## 4. Add a new column: transaction_month
df['month'] = df['date'].dt.strftime('%Y-%m')
## 5. Group by month and status
monthly_by_status = df.groupby(['month', 'status']).agg({
'transaction_id': 'count',
'amount': 'sum'
}).rename(columns={'transaction_id': 'count'})
## Calculate success rate by month (completed / total)
print("\nTransaction success rates by month:")
for month, month_data in df.groupby('month'):
total = len(month_data)
completed = len(month_data[month_data['status'] == 'completed'])
success_rate = (completed / total) * 100
print(f" {month}: {success_rate:.1f}% ({completed}/{total})")
## Save filtered data to a new CSV file
completed_high_value = df[(df['status'] == 'completed') & (df['amount'] > 300)]
output_file = 'high_value_completed.csv'
completed_high_value.to_csv(output_file, index=False)
end_time = time.time()
print(f"\nFiltering completed in {end_time - start_time:.2f} seconds")
print(f"Saved {len(completed_high_value)} high-value completed transactions to {output_file}")
## Filter and transform the data
filter_and_transform('transactions.csv')
Exécutez ce script :
python3 pandas_filter.py
Sortie attendue :
Filtering and transforming data from transactions.csv...
Number of completed transactions: 12432
Number of high-value transactions (>$400): 6190
Number of transactions in Q1 2022: 12348
Transaction success rates by month:
2022-01: 24.8% (1048/4225)
2022-02: 25.0% (1010/4034)
2022-03: 25.4% (1042/4089)
2022-04: 24.2% (978/4052)
2022-05: 24.4% (1047/4297)
2022-06: 24.4% (1046/4280)
2022-07: 24.7% (1071/4341)
2022-08: 25.1% (1090/4343)
2022-09: 26.1% (1091/4177)
2022-10: 24.1% (1008/4182)
2022-11: 24.8% (1009/4075)
2022-12: 25.2% (992/3905)
Filtering completed in 0.38 seconds
Saved 6304 high-value completed transactions to high_value_completed.csv
Avantages de l'utilisation de Pandas
Comme vous pouvez le constater à partir de ces exemples, pandas offre plusieurs avantages pour le traitement CSV :
- Fonctionnalités riches : Méthodes intégrées pour le filtrage, le regroupement, l'agrégation et la transformation des données
- Performance : Code C optimisé en arrière-plan pour des opérations rapides sur de grands ensembles de données
- Analyse de données facile : Moyens simples de calculer des statistiques et d'obtenir des informations
- Capacités de visualisation : Intégration facile avec les bibliothèques de traçage (non illustrée dans les exemples)
- Traitement par blocs : Capacité à gérer des fichiers plus volumineux que la mémoire disponible
Pour la plupart des tâches d'analyse de données impliquant des fichiers CSV, pandas est l'approche recommandée, sauf si vous avez des contraintes de mémoire spécifiques qui nécessitent l'utilisation du module csv en pur Python.
Résumé
Dans ce tutoriel, vous avez appris plusieurs approches pour traiter efficacement les fichiers CSV en Python, des petits ensembles de données aux grands ensembles qui nécessitent une gestion minutieuse de la mémoire :
Traitement CSV de base : Utilisation du module
csvintégré de Python pour lire et écrire des fichiers CSV aveccsv.readeretcsv.writer.Traitement basé sur des dictionnaires : Utilisation de
csv.DictReaderpour travailler avec les données CSV de manière plus intuitive, en accédant aux champs par nom au lieu de l'index.Techniques de traitement efficaces :
- Streaming (flux) : Traitement des fichiers ligne par ligne pour une utilisation minimale de la mémoire
- Chunking (traitement par blocs) : Traitement des fichiers par lots pour une meilleure gestion de la mémoire
Traitement avancé avec Pandas :
- Lecture de fichiers CSV dans des DataFrames
- Analyse et filtrage des données
- Traitement de fichiers volumineux par blocs
- Transformation et exportation des données
Ces techniques fournissent une boîte à outils complète pour la gestion des fichiers CSV de toute taille en Python. Pour la plupart des tâches d'analyse de données, pandas est la bibliothèque recommandée en raison de ses riches fonctionnalités et de ses performances. Cependant, pour les très grands fichiers ou les tâches de traitement simples, les approches de streaming et de chunking avec le module csv intégré peuvent être plus efficaces en termes de mémoire.
En appliquant la technique appropriée en fonction de vos besoins spécifiques, vous pouvez traiter efficacement les fichiers CSV de toute taille sans rencontrer de problèmes de mémoire.



