Pandas apply / map / applymap

apply, map und applymap sind die drei wichtigsten Funktionen in Pandas für die Datentransformation. Sie können flexible elementweise oder Batch-Operationen auf DataFrame oder Series ausführen.


Series.map

mapIst eine Series-Methode, mit der jedes Element in einer Series transformiert wird.

Grundlegende Verwendung

Beispiel

import pandas as pd

# Series erstellen
s = pd.Series([1, 2, 3, 4, 5])

print("Originaldaten:")
print(s)
print()

# Eine Funktion verwenden
print("Jedes Element * 2:")
print(s.map(lambda x: x * 2))
print()

# Dictionary-Mapping verwenden
mapping = {1: "A", 2: "B", 3: "C", 4: "D", 5: "E"}
print("Dictionary-Mapping wird verwendet:")
print(s.map(mapping))
print()

# Series-Mapping verwenden
mapping_series = pd.Series(["A", "B", "C", "D", "E"], index=[1, 2, 3, 4, 5])
print("Verwende Series-Mapping:")
print(s.map(mapping_series))

Umgang mit fehlenden Werten

Beispiel

import pandas as pd
import numpy as np

s = pd.Series([1, 2, np.nan, 4, 5])

print("Enthält NaN:")
print(s)
print()

# map überspringt NaN standardmäßig
print("map-Verhalten (überspringt NaN):")
print(s.map(lambda x: x * 2 if pd.notna(x) else -1))

DataFrame.applymap

applymapIst eine DataFrame-Methode, die eine Funktion nacheinander auf jedes Element anwendet (Hinweis: Pandas 2.0+ empfiehlt die Verwendung vonDataFrame.mapstattdessen).

Beispiel

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "A": [1, 2, 3],
    "B": [4, 5, 6],
    "C": [7, 8, 9]
})

print("Originaldaten:")
print(df)
print()

# Jedes Element mit 2 multiplizieren
print("Jedes Element * 2:")
print(df.applymap(lambda x: x * 2))
print()

# 2 Dezimalstellen beibehalten
print("2 Dezimalstellen beibehalten:")
print(df.applymap(lambda x: round(x, 2)))

applymap führt elementweise Operationen aus und kann bei großen Datenmengen langsam sein. Wenn Sie nur mit numerischen Spalten arbeiten müssen, sollten Sie vektorisierte Operationen oder apply mit dem axis-Parameter in Betracht ziehen.


DataFrame.apply

applyIst die flexibelste Methode und kann Funktionen entlang einer Achse anwenden.

Spaltenweise anwenden

Beispiel

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "A": [1, 2, 3, 4, 5],
    "B": [10, 20, 30, 40, 50],
    "C": [100, 200, 300, 400, 500]
})

print("Originaldaten:")
print(df)
print()

# Standard axis=0, spaltenweise anwenden
print("Spaltensumme:")
print(df.apply(sum))
print()

print("Spaltenmaximum:")
print(df.apply(max))

Zeilenweise anwenden

Beispiel

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "A": [1, 2, 3],
    "B": [10, 20, 30],
    "C": [100, 200, 300]
})

print("Originaldaten:")
print(df)
print()

# axis=1, zeilenweise anwenden
print("Zeilensumme:")
print(df.apply(sum, axis=1))
print()

# Max - min pro Zeile
print("Zeilen-Spannweite:")
print(df.apply(lambda x: x.max() - x.min(), axis=1))

aggfunc für Aggregation verwenden

Beispiel

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "A": [1, 2, 3],
    "B": [10, 20, 30]
})

# Mehrere Funktionen gleichzeitig anwenden
print("Summe und Mittelwert gleichzeitig:")
print(df.apply([sum, np.mean]))
print()

# Mehrere Werte zurückgeben
result = df.apply(lambda x: pd.Series({
    "sum": x.sum(),
    "mean": x.mean(),
    "max": x.max()
}, index=["sum", "mean", "max"]))

print("Rückgabe mehrerer Werte:")
print(result)

Series.apply

Series kann auch apply verwenden, was ähnlich wie map, aber flexibler ist.

Beispiel

import pandas as pd
import numpy as np

s = pd.Series([1, 4, 9, 16, 25])

print("Originaldaten:")
print(s)
print()

# Quadratwurzel
print("Quadratwurzel:")
print(s.apply(np.sqrt))
print()

# Bedingte Rückgabe
print("Bedingte Prüfung:")
print(s.apply(lambda x: "groß" if x > 10 else "klein"))

Leistungsvergleich

Beispiel

import pandas as pd
import numpy as np
import time

# Große Daten erstellen
n = 100000
s = pd.Series(np.random.randn(n))

# map vs. apply testen
func = lambda x: x * 2 + 1

start = time.time()
result1 = s.map(func)
map_time = time.time() - start

start = time.time()
result2 = s.apply(func)
apply_time = time.time() - start

# Vektorisiert (am schnellsten)
start = time.time()
result3 = s * 2 + 1
vec_time = time.time() - start

print(f"map-Zeit: {map_time:.4f}s")
print(f"apply-Zeit: {apply_time:.4f}s")
print(f"Vektorisierte Zeit: {vec_time:.4f}s")

print("\nFazit: Priorisiere vektorisierte Operationen für beste Leistung")

Praxis: Datentransformation

Beispiel

import pandas as pd
import numpy as np

# Beispiel-DataFrame erstellen
df = pd.DataFrame({
    "Name": ["Zhang San", "Li Si", "Wang Wu", "Zhao Liu"],
    "Alter": [25, 30, 28, 35],
    "Salary": [12000, 15000, 11000, 18000],
    "Department": ["Technology", "Sales", "Technology", "Operations"]
})

print("Originaldaten:")
print(df)
print()

# apply für Berechnung auf Zeilenebene verwenden
def calculate(row):
    """Jahreseinkommen und Gehalt nach Steuern berechnen"""
    annual = row["Salary"] * 12
    tax = annual * 0.1 if annual > 120000 else annual * 0.05
    after_tax = annual - tax
    return pd.Series({
        "Annual salary": annual,
        "Tax": tax,
        "After tax": after_tax
    })

result = df.apply(calculate, axis=1)
df_result = pd.concat([df, result], axis=1)

print("Berechnungsergebnisse:")
print(df_result)

Auswahl unter den dreien

Methode Anwendbares Objekt Szenario Leistung
map Serie Elementweise Transformation, Wörterbuchzuordnung Schnell
applymap DataFrame Elementweise Transformation (nicht-numerische Spalten) Langsam
apply Series/DataFrame Zeilen-/Spaltenaggregation, benutzerdefinierte Funktionen Mittel

Wenn vektorisierte Operationen (direkte Verwendung von Operatoren) verfügbar sind, apply/map nicht verwenden; wenn map verfügbar ist, apply nicht verwenden.

Andere Erweiterungen