Ga naar hoofdinhoud

Pandas .apply(): wat het doet, wanneer het helpt en snellere alternatieven

Leer wat Python pandas .apply is en hoe je het gebruikt voor DataFrames. Leer vandaag nog hoe je over DataFrames itereert met de functie .apply()!
Bijgewerkt 2 okt 2026  · 5 min lezen

Verken met AI

ChatGPTClaudePerplexity

Veel mensen grijpen naar .apply() om “loops te vermijden” en verwachten dat het snel en eenvoudig is. In de praktijk is rijgewijs .apply(axis=1) nog steeds een loop op Python-niveau. Het kan traag zijn bij grote datasets en soms levert het vormen op die je niet verwacht. De oplossing is simpel: gebruik gevectoriseerde pandas/NumPy-bewerkingen voor veelvoorkomende taken en bewaar .apply() voor logica die echt meerdere kolommen nodig heeft.

Deze gids laat zien hoe .apply() vandaag werkt, benoemt veelgemaakte valkuilen en geeft kant-en-klare patronen die sneller en duidelijker zijn.

Wat zijn DataFrame.apply() en Series.apply()?

DataFrame.apply(func, axis=0) roept standaard func aan op elke kolom. Met axis=1 roept het func aan op elke rij. Series.apply(func) roept func aan op elk element (of op de hele Series, afhankelijk van signaturen in recente versies).

  • Rijgewijs vs. kolomgewijs: axis=1 betekent “per rij.” axis=0 (de standaard) betekent “per kolom.”
  • Regels voor retourvorm (pandas ≥0.23): Als je functie een scalar per rij/kolom retourneert, krijg je een Series. Als deze een Series of dict retourneert, zet pandas die sleutels uit naar een DataFrame. Als het een lijst/array retourneert, krijg je een Series van lijsten tenzij je result_type='expand' instelt.
  • Strengere fouten (pandas ≥2.0): Ongelijke lengtes van list-achtige resultaten geven nu errors in plaats van stilzwijgend inconsistente resultaten op te leveren.

Aanbevolen eerste keuze: gevectoriseerde bewerkingen

De meeste taken waarbij je kolommen combineert of transformeert zijn sneller en duidelijker met gevectoriseerde expressies of ingebouwde methodes. Het volgende voorbeeld berekent het run-differentieel van een honkbalteam zonder .apply().

import pandas as pd

team_stats = pd.DataFrame({
    "Team": ["ARI", "ATL", "BAL"],
    "League": ["NL", "NL", "AL"],
    "Year": [2012, 2012, 2012],
    "RunsScored": [734, 700, 712],
    "RunsAllowed": [688, 600, 705],
    "Wins": [81, 94, 93],
    "Games": [162, 162, 162],
    "Playoffs": [0, 1, 1],
})

# Vectorized: fast and idiomatic
team_stats["RunDiff"] = team_stats["RunsScored"] - team_stats["RunsAllowed"]
print(team_stats[["Team", "RunsScored", "RunsAllowed", "RunDiff"]])

Rijgewijze .apply() wanneer je het echt nodig hebt

Gebruik .apply(axis=1) wanneer je logica echt meerdere kolommen beslaat en niet eenvoudig te vectoriseren is (bijvoorbeeld voorwaardelijke regels die van meerdere velden afhangen).

een afgeleide waarde uit meerdere kolommen berekenen

Dit patroon berekent per rij een waarde met meerdere inputs. De gevectoriseerde aanpak hierboven heeft nog steeds de voorkeur, maar dit laat het correcte rijgewijze gebruik en opties zien die snelheid en output beïnvloeden.

def compute_run_diff(row):
    # Treat the row as read-only; return a scalar
    return row["RunsScored"] - row["RunsAllowed"]

# Row-wise apply (Python-level loop; can be slow on large data)
team_stats["RunDiff_apply"] = team_stats.apply(compute_run_diff, axis=1)

Wanneer de functie numeriek is en alleen ruwe arrays nodig heeft, sla je met raw=True een deel van de pandas-overhead over door je functie een NumPy-array te geven.

import numpy as np

def compute_run_diff_raw(values):
    # values is a NumPy array when raw=True
    # Order matches the column order we select
    rs, ra = values
    return rs - ra

team_stats["RunDiff_raw"] = team_stats[["RunsScored", "RunsAllowed"]].apply(
    compute_run_diff_raw, axis=1, raw=True
)

de invoer van de functie één keer verifiëren

Als ik een nieuwe rijfunctie aansluit, print ik één keer een rij om te bevestigen wat er wordt doorgegeven.

def debug_row(row):
    # Print the first row only
    if row.name == team_stats.index[0]:
        print("Example row:", row.to_dict())
    return 0

_ = team_stats.apply(debug_row, axis=1)

Casestudy: sommen, seizoentotalen en tekstvlaggen

Gegeven Rays-per-jaarstatistieken, geef waar mogelijk de voorkeur aan ingebouwde methodes en elementgewijze tools boven .apply().

rays_by_year = pd.DataFrame(
    {
        "Year": [2012, 2011, 2010, 2009, 2008],
        "RunsScored": [697, 707, 802, 803, 774],
        "RunsAllowed": [577, 614, 649, 754, 671],
        "Wins": [90, 91, 96, 84, 97],
        "Playoffs": [0, 1, 1, 0, 1],
    }
).set_index("Year")

kolomsommen efficiënt ophalen

Gebruik DataFrame.sum() in plaats van .apply(sum). Dat is sneller en duidelijker.

# Preferred
totals = rays_by_year.sum(axis=0)
print(totals)

# If you must use apply (not recommended here)
totals_apply = rays_by_year.apply(sum, axis=0)

totaal aantal gescoorde runs in een seizoen berekenen

Gebruik gevectoriseerde rekenkunde over kolommen; geen .apply() nodig.

rays_by_year["TotalRuns"] = rays_by_year["RunsScored"] + rays_by_year["RunsAllowed"]
print(rays_by_year[["RunsScored", "RunsAllowed", "TotalRuns"]].head())

een 0/1-vlag omzetten naar tekst

Geef de voorkeur aan Series.map() of replace() voor elementgewijze transformaties op één kolom.

# Using map with a dict
rays_by_year["PlayoffsText"] = rays_by_year["Playoffs"].map({0: "No", 1: "Yes"})

# Equivalent with replace
rays_by_year["PlayoffsText2"] = rays_by_year["Playoffs"].replace({0: "No", 1: "Yes"})

Beheers de outputvorm van .apply()

Wanneer je functie meer dan één waarde per rij retourneert, maak de vorm expliciet. Zo voorkom je verrassingen en problemen bij toekomstige versies.

een lijst retourneren en uitvouwen naar kolommen

Gebruik result_type='expand' om een lijst/array over meerdere kolommen te splitsen.

def wins_losses(row):
    # Derive wins and losses as two outputs
    wins = row["Wins"]
    losses = row["Games"] - row["Wins"] if "Games" in row else np.nan
    return [wins, losses]

# Example using team_stats, which has "Wins" and "Games"
expanded = team_stats.apply(wins_losses, axis=1, result_type="expand")
expanded.columns = ["WinsOut", "LossesOut"]
team_stats = pd.concat([team_stats, expanded], axis=1)

een series of dict retourneren om kolommen automatisch te benoemen

Een Series of dict per rij retourneren levert een DataFrame op met overeenkomstige kolomlabels.

def summary_row(row):
    return pd.Series(
        {
            "IsWinningSeason": row["Wins"] >= 90,
            "RunRatio": (row["RunsScored"] / row["RunsAllowed"]),
        }
    )

summary = team_stats.apply(summary_row, axis=1)
team_stats = pd.concat([team_stats, summary], axis=1)

Prestatie-tips die ertoe doen

Rijgewijs .apply(axis=1) is handig maar traag op grote frames omdat je Python-functie één keer per rij wordt aangeroepen. Deze patronen vermijden die bottleneck.

  • Geef de voorkeur aan gevectoriseerde pandas/NumPy-bewerkingen en ingebouwde methodes zoals sum, mean, clip, where, astype en string-/accessormethodes.
  • Voor numerieke rij-/kolombewerkingen die arrays accepteren, geef raw=True mee om een NumPy-array te krijgen en pandas-overhead te verminderen.
  • Voor elementgewijs werk aan één kolom, gebruik Series.map() of gevectoriseerde methodes in plaats van DataFrame.apply(axis=1).
  • Voorkom mutatie van de aangeleverde rij/kolom binnen je functie; retourneer in plaats daarvan een nieuwe waarde.

Versie-opmerkingen die je moet kennen (pandas 2.x)

Recente pandas-releases hebben het gedrag rond .apply() aangescherpt, zodat resultaten voorspelbaarder zijn.

  • List-achtige returns: In 2.0+ geven ongelijke lijstlengtes een error. Gebruik consistente lengtes en stel result_type='expand' in wanneer je meerdere kolommen wilt.
  • Uitvouwing van output: Een Series of dict retourneren zet uit naar een DataFrame met die keys als kolommen (stabiel sinds 0.23).
  • Series.apply()-wijzigingen: Het argument convert_dtype is verouderd. Als je gemengde types nodig hebt, cast dan eerst naar object (bijvoorbeeld s.astype("object").apply(fn)). Nieuwere signaturen laten beter regelen of fn scalars of een Series ontvangt in meer contexten (bijvoorbeeld by_row).

.apply() vs. .map() vs. .applymap() vs. .agg()

Kies de API die past bij de vorm van je transformatie.

  • Series.map(func_or_dict): Elementgewijze transformatie op één kolom. Ideaal voor lookups of eenvoudige functies.
  • DataFrame.apply(func, axis=1): Rijgewijze logica die meerdere kolommen nodig heeft.
  • DataFrame.apply(func, axis=0): Kolomgewijze logica (elke input is een Series die een kolom voorstelt).
  • DataFrame.applymap(func): Elementgewijs over elke cel. Gebruik spaarzaam; gevectoriseerde methodes zijn sneller.
  • .agg()/.transform(): Aggregaties en groepstransformaties; geef hier de voorkeur aan in groupby-pijplijnen.

Veelgemaakte fouten en snelle oplossingen

Dit zijn de problemen die het vaakst tot onjuiste resultaten of vertragingen leiden, met manieren om ze te verhelpen.

  • axis=1 vergeten voor per-rijlogica: Krijgt je functie ineens kolommen in plaats van rijen binnen, voeg dan axis=1 toe.
  • Onverwachte Series van lijsten: Wanneer je per rij een lijst/array retourneert, stel result_type='expand' in om te splitsen naar kolommen.
  • Trage rijgewijze code: Vervang door gevectoriseerde expressies of ingebouwde functies; als dat niet kan, overweeg raw=True om overhead te verminderen.
  • De invoerrij muteren: Behandel inputs als read-only en retourneer nieuwe waarden.
  • Dtype-drift: Als je functie soms niet-integers retourneert, kunnen integerkolommen opcasten naar float of object. Cast achteraf met astype indien nodig.

Conclusie

.apply() is een flexibel hulpmiddel, maar geen prestatiesnelkoppeling. Gebruik gevectoriseerde bewerkingen voor rekenwerk, aggregatie en elementgewijze transformaties op één kolom. Grijp naar DataFrame.apply(axis=1) alleen wanneer je logica echt meerdere kolommen per rij nodig heeft. Als je het gebruikt, beheer dan de outputvorm met result_type, overweeg raw=True voor numerieke functies en let op dtypes. Deze patronen leveren voorspelbare resultaten op in moderne pandas en schalen beter naarmate je data groeit.

Onderwerpen
Python

Leer meer over Python en pandas

Cursus

Datamanipulatie met pandas

4 uur
568.2K
Leer hoe je data importeert en opschoont, statistieken berekent en visualisaties maakt met pandas.
Bekijk detailsRight Arrow
Start Cursus
Meer bekijkenRight Arrow
Gerelateerd

blog

AI vanaf nul leren in 2026: een complete gids van de experts

Ontdek alles wat je moet weten om in 2026 AI te leren, van tips om te beginnen tot handige resources en inzichten van industrie-experts.
Adel Nehme's photo

Adel Nehme

15 min

Meer BekijkenMeer Bekijken