Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 .pipe voor 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 .loc voor 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 pyarrow engine voor read_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 .pipe voor onderhoudbaarheid.
  • Meet, vergelijk, en documenteer performance‑winst.