Hoofdstuk 19 — Prestatie, memory en method‑chaining (pipe)
Let op: De tekst is in het Nederlands; alle Python codevoorbeelden zijn in het Engels.
Doel van dit hoofdstuk:
- Begrijpen van geheugenverbruik en dtypes; kolom‑selectie en kopieën vermijden.
- Vectorisatie, blokgewijze verwerking en efficiënte I/O.
- Method‑chaining en functionele stijl met
.pipevoor onderhoudbare pipelines. - Profiling en meetbare optimalisaties.
Aanbevolen voorkennis: Hoofdstuk 13–18.
19.1 Geheugeninspectie en dtypes
import pandas as pd
import numpy as np
df = pd.DataFrame({
'id': np.arange(1_000_000),
'cat': np.random.choice(list('ABCDE'), size=1_000_000),
'x': np.random.rand(1_000_000)
})
mem_before = df.memory_usage(deep=True).sum() / 1e6
# Optimaliseer dtypes
df['id'] = df['id'].astype('int32')
df['cat'] = df['cat'].astype('category')
df['x'] = df['x'].astype('float32')
mem_after = df.memory_usage(deep=True).sum() / 1e6
print(mem_before, mem_after)
19.2 Kopieën vermijden en chained assignment
- Gebruik
.locvoor veilige toewijzing:df.loc[mask, 'col'] = value. - Vermijd kettingindexering
df[df.a>0]['b'] = ...(SettingWithCopyWarning). - Werk kolomgewijs en benut ufuncs; vermijd per‑rij loops.
19.3 Vectorisatie en blokgewijze verwerking
# Vectorized
df['y'] = df['x'] * 2 + 1
# Blokgewijs lezen/verwerken bij grote CSV's
it = pd.read_csv('big.csv', chunksize=100_000)
acc = 0.0
for chunk in it:
acc += (chunk['qty'] * chunk['price']).sum()
19.4 Efficiënte I/O en opslag
- Gebruik Parquet met compressie (snappy/zstd) i.p.v. CSV voor herhaald lezen.
- Sla alleen benodigde kolommen op; gebruik
columns=bij Parquet. - Partitioneer datasets op logische sleutels (jaar/maand) voor slice‑toegang.
19.5 Method‑chaining en .pipe
def add_amount(d):
return d.assign(amount=d['qty'] * d['price'])
def filter_valid(d):
return d.dropna(subset=['product', 'qty', 'price'])
def normalize_amount(d):
mean = d['amount'].mean(); std = d['amount'].std()
return d.assign(amount_z=(d['amount'] - mean)/std)
result = (
pd.read_csv('transactions.csv', sep=';', parse_dates=['date'])
.pipe(filter_valid)
.pipe(add_amount)
.query('qty > 0 and price > 0')
.pipe(normalize_amount)
.sort_values(['date'])
)
19.6 Profiling en timing
# Eenvoudig tijd meten
import time
start = time.perf_counter()
_ = pd.read_csv('big.csv')
elapsed = time.perf_counter() - start
print(f"read_csv: {elapsed:.3f}s")
# memory_usage en info
mu = result.memory_usage(deep=True).sum()/1e6
print(f"Result MB: {mu:.2f}")
19.7 Parallel/alternatieve engines (kort)
- Gebruik
pyarrowengine voorread_csv(indien beschikbaar in recente pandas) voor snelheidswinst. - Voor zeer grote data: overweeg Dask/Polars/Spark (buiten scope), maar principes blijven gelijk.
19.8 Samenvatting
- Beperk geheugen via dtypes en kolomselectie; voorkom onnodige kopieën.
- Vectoriseer berekeningen en verwerk streamend met chunks.
- Structureer data pipelines met method‑chaining en
.pipevoor onderhoudbaarheid. - Meet, vergelijk, en documenteer performance‑winst.