0Pricing
Pandas & NumPy Academy · Lektion

Rang und Perzentil innerhalb von Gruppen

Berechnen Sie mit groupby().rank() Ränge innerhalb von Gruppen und erstellen Sie mit pd.qcut Perzentilklassen für relative Vergleiche.

Rang und Perzentil innerhalb von Gruppen ist eine kostenlose Pandas & NumPy Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Pandas & NumPy Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.

Warum innerhalb von Gruppen Ränge bilden?

Rohwerte sind oft weniger aussagekräftig als relative Rangpositionen. Ein Vertriebsmitarbeiter mit einem monatlichen Umsatz von 50.000 $ ist ein Spitzenmitarbeiter, wenn der Durchschnitt bei 30.000 $ liegt, aber ein leistungsschwacher Mitarbeiter, wenn der Durchschnitt 80.000 $ beträgt. Wenn Sie Ränge innerhalb von Gruppen berechnen (z. B. innerhalb jeder Region oder jedes Quartals), erhalten Sie einen normalisierten Vergleich, der unterschiedliche Ausgangsniveaus zwischen Gruppen berücksichtigt. Pandas erleichtert die Rangbildung innerhalb von Gruppen mit groupby().rank().

import pandas as pd
import numpy as np

np.random.seed(42)
df = pd.DataFrame({
    'rep': ['Alice', 'Bob', 'Carol', 'Dave', 'Eve',
            'Frank', 'Grace', 'Hank', 'Iris', 'Jake'],
    'region': ['East']*5 + ['West']*5,
    'sales': np.random.randint(30000, 100000, 10)
})
print(df.sort_values('region'))

Series.rank() — Grundlegende Rangbildung

Series.rank() weist jedem Wert einen Rang zu: Rang 1 ist der kleinste, Rang n der größte Wert. Der Parameter ascending=False kehrt die Richtung um, sodass Rang 1 dem größten Wert entspricht. Das Ergebnis ist eine Series vom Typ Float (keine Ganzzahl), weil gleiche Werte standardmäßig durch den Mittelwert der gebundenen Ränge behandelt werden. Bei einer Spalte mit 5 Werten reichen die Ränge von 1.0 bis 5.0 – bei gleichen Werten können sich einige Werte jedoch einen Rang wie 2.5 teilen.

import pandas as pd

s = pd.Series([80, 45, 90, 45, 70])

print('Values:', s.values)
print('Rank (ascending=True, default):', s.rank().values)
print('Rank (ascending=False — best=1):', s.rank(ascending=False).values)
# Note: two 45s share ranks 1 and 2 → both get 1.5

Methoden zur Auflösung von Rangbindungen in rank()

Der Parameter method legt fest, wie gleiche Werte behandelt werden. Optionen: 'average' (Standard – gleiche Werte erhalten den Mittelwert ihrer Ränge), 'min' (alle gleichen Werte erhalten den niedrigsten Rang), 'max' (alle erhalten den höchsten Rang), 'first' (Ränge werden in der Reihenfolge des Auftretens vergeben – keine Bindungen) und 'dense' (keine Lücken in den Rängen – 1, 2, 3, 3, 4 wird zu 1, 2, 3, 3, 4 statt zu 1, 2, 3, 3, 5). Die Methode 'dense' eignet sich besonders für Rangbildungen im Perzentilstil.

import pandas as pd

s = pd.Series([80, 45, 90, 45, 70])

result = pd.DataFrame({
    'value': s,
    'average': s.rank(method='average'),
    'min': s.rank(method='min'),
    'max': s.rank(method='max'),
    'first': s.rank(method='first'),
    'dense': s.rank(method='dense')
})
print(result)

Rangbildung innerhalb von Gruppen mit groupby().rank()

groupby('group_col')['value_col'].rank() berechnet Ränge unabhängig innerhalb jeder Gruppe. Der Rang wird am Anfang jeder Gruppe zurückgesetzt – der beste Mitarbeiter in der Region East erhält also in East den Rang 1, und der beste Mitarbeiter in West ebenfalls den Rang 1 in West. Dadurch eignet sich groupby rank so gut für faire Vergleiche zwischen Gruppen.

import pandas as pd
import numpy as np

np.random.seed(42)
df = pd.DataFrame({
    'rep': list('ABCDEABCDE'),
    'region': ['East']*5 + ['West']*5,
    'sales': np.random.randint(30000, 100000, 10)
})

# Rank within each region (best = rank 1)
df['rank_in_region'] = df.groupby('region')['sales'].rank(ascending=False, method='min')
df_sorted = df.sort_values(['region', 'rank_in_region'])
print(df_sorted.to_string(index=False))

Perzentilrang mit rank(pct=True)

Wenn Sie in rank() pct=True setzen, wird der Perzentilrang zurückgegeben: ein Wert zwischen 0 und 1, der angibt, welcher Anteil der Werte in der Gruppe kleiner oder gleich dem aktuellen Wert ist. Ein Perzentilrang von 0.8 bedeutet, dass der Wert im 80. Perzentil liegt – er ist größer als 80 % aller Werte. Durch diese Normalisierung lassen sich Werte aus Gruppen unterschiedlicher Größe direkt vergleichen, ohne die tatsächliche Gruppengröße zu kennen.

import pandas as pd
import numpy as np

np.random.seed(0)
df = pd.DataFrame({
    'name': list('ABCDEFGHIJ'),
    'region': ['East']*5 + ['West']*5,
    'score': np.random.randint(50, 100, 10)
})

# Percentile rank within region
df['pct_rank'] = df.groupby('region')['score'].rank(pct=True)
df['percentile'] = (df['pct_rank'] * 100).round(0).astype(int)
print(df.sort_values(['region', 'percentile'], ascending=[True, False]).to_string(index=False))

pd.qcut: Binning auf Quantilbasis

pd.qcut(series, q) teilt Werte in q gleich häufig besetzte Intervalle auf, sodass jedes Intervall ungefähr die gleiche Anzahl an Beobachtungen enthält. Im Gegensatz zu pd.cut, das Intervalle gleicher Breite verwendet, passt pd.qcut die Intervallgrenzen an die Verteilung der Daten an. Das eignet sich ideal zum Erstellen von Quartilen (q=4), Quintilen (q=5) oder Dezilen (q=10) für Leistungsstufen.

import pandas as pd
import numpy as np

np.random.seed(42)
sales = pd.Series(np.random.exponential(scale=50000, size=100))

# Divide into quartiles
quartiles = pd.qcut(sales, q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])

result = pd.DataFrame({'sales': sales, 'quartile': quartiles})
print('Quartile counts (should be ~25 each):')
print(result['quartile'].value_counts().sort_index())
print('\nMean sales per quartile:')
print(result.groupby('quartile')['sales'].mean().round(0))

pd.cut im Vergleich zu pd.qcut

pd.cut(series, bins=n) erstellt Intervalle gleicher Breite (gleiche Spannweite, unterschiedliche Anzahl an Werten). pd.qcut(series, q=n) erstellt Intervalle gleicher Häufigkeit (gleiche Anzahl an Werten, unterschiedliche Spannweiten). Bei schief verteilten Daten sind die Intervalle am Rand bei pd.cut nahezu leer, während pd.qcut die Beobachtungen gleichmäßig verteilt. Wählen Sie pd.cut, wenn die Intervallgrenzen eine natürliche geschäftliche Bedeutung haben (Preisspannen, Altersgruppen), und pd.qcut für Leistungsstufen, bei denen Sie gleich große Gruppen erhalten möchten.

import pandas as pd
import numpy as np

np.random.seed(0)
# Right-skewed data
data = pd.Series(np.random.exponential(1, 100))

cut_result = pd.cut(data, bins=5).value_counts().sort_index()
qcut_result = pd.qcut(data, q=5).value_counts().sort_index()

print('Equal-width bins (pd.cut) — uneven counts:')
print(cut_result.to_string())
print('\nEqual-frequency bins (pd.qcut) — even counts:')
print(qcut_result.to_string())

Dezillabels mit pd.qcut erstellen

pd.qcut(series, q=10, labels=range(1,11)) weist jede Beobachtung ihrem Dezil (1 bis 10) zu. Dies ist eine Standardtechnik in der Marketinganalyse (Kundenswertdezile), bei der Kreditbewertung (Risikodezile) und bei AB-Tests (Trafficdezile zur Kohortenanalyse). Der Parameter labels kann jede Liste mit derselben Länge wie q sein – verwenden Sie für eine besser lesbare Ausgabe Zeichenketten wie ['Bottom 10%', ..., 'Top 10%'].

import pandas as pd
import numpy as np

np.random.seed(7)
customer_value = pd.Series(np.random.exponential(500, 1000))

# Assign to deciles 1-10
decile_labels = [f'D{i}' for i in range(1, 11)]
customer_decile = pd.qcut(
    customer_value,
    q=10,
    labels=decile_labels
)

result = pd.DataFrame({'value': customer_value, 'decile': customer_decile})
print('Mean customer value per decile:')
print(result.groupby('decile')['value'].mean().round(0))

Perzentilintervalle innerhalb von Gruppen

Kombinieren Sie groupby mit pd.qcut und verwenden Sie transform, um Perzentilintervalle innerhalb jeder Gruppe zu erstellen. Das ist nützlich, wenn Sie Kunden innerhalb jeder Region statt global einordnen möchten – ein Kunde im globalen unteren Dezil kann im Dezil seiner Region an der Spitze liegen. Verwenden Sie groupby('group')['value'].transform(lambda x: pd.qcut(x, q=4, labels=['Q1','Q2','Q3','Q4'])).

import pandas as pd
import numpy as np

np.random.seed(42)
df = pd.DataFrame({
    'customer': range(20),
    'region': ['North']*10 + ['South']*10,
    'spend': np.random.randint(100, 1000, 20)
})

# Quartile within each region
def quartile_label(x):
    return pd.qcut(x, q=4, labels=['Q1','Q2','Q3','Q4'])

df['region_quartile'] = df.groupby('region')['spend'].transform(quartile_label)
print(df.sort_values(['region', 'region_quartile']).to_string(index=False))

Top-N innerhalb von Gruppen

Eine häufige geschäftliche Frage lautet: „Wer sind die drei leistungsstärksten Mitarbeiter in jeder Region?“ Verwenden Sie groupby().rank() und filtern Sie anschließend nach dem Rang: df[df['rank_col'] <= 3]. Dies funktioniert unabhängig von der Gruppengröße und behandelt Bindungen auf sinnvolle Weise, indem bei gleichen Rängen am Grenzwert mehr als drei Zeilen beibehalten werden. Alternativ können Sie groupby().nlargest(n) verwenden, das direkt die n größten Werte je Gruppe zurückgibt, ohne eine Rangspalte hinzuzufügen.

import pandas as pd
import numpy as np

np.random.seed(0)
df = pd.DataFrame({
    'rep': [f'Rep_{i}' for i in range(15)],
    'region': ['East']*5 + ['West']*5 + ['North']*5,
    'revenue': np.random.randint(40000, 120000, 15)
})

df['region_rank'] = df.groupby('region')['revenue'].rank(ascending=False, method='min')

print('Top 2 per region:')
top2 = df[df['region_rank'] <= 2].sort_values(['region', 'region_rank'])
print(top2[['rep', 'region', 'revenue', 'region_rank']].to_string(index=False))

Rang und Transform zur Normalisierung kombinieren

Sie können groupby().rank(pct=True) mit transform kombinieren, um dem ursprünglichen DataFrame eine Perzentilrangspalte hinzuzufügen. Diese normalisierte Spalte ist als Modellmerkmal oft nützlicher als der Rohwert – sie ist skalenunabhängig und zwischen Gruppen vergleichbar. Im maschinellen Lernen sind Perzentilränge eine einfache Alternative zur Standardisierung (z-Transformation), die robuster gegenüber Ausreißern ist.

import pandas as pd
import numpy as np

np.random.seed(1)
df = pd.DataFrame({
    'product': np.random.choice(['A', 'B', 'C'], 30),
    'score': np.random.randint(50, 100, 30)
})

# Percentile rank within each product group
df['global_pct'] = df['score'].rank(pct=True).round(3)
df['group_pct'] = df.groupby('product')['score'].rank(pct=True).round(3)

print(df.sort_values(['product', 'score']).head(12).to_string(index=False))

Kurzer Wissenstest

Testen Sie Ihr Verständnis der Rang- und Perzentiloperationen aus dieser Lektion.

Zusammenfassung der Lektion

In dieser Lektion haben Sie gelernt: Series.rank() berechnet numerische Ränge mit konfigurierbarer Auflösung von Rangbindungen, groupby().rank() setzt die Ränge innerhalb jeder Gruppe zurück und ermöglicht dadurch faire Vergleiche zwischen Gruppen, pct=True wandelt Ränge in Perzentile (0 bis 1) um, und pd.qcut erstellt Intervalle gleicher Häufigkeit für Quartil-, Dezil- und Perzentilstufen. Als Nächstes untersuchen wir Tipps zur Pandas-Performance – Profiling, das Vermeiden langsamer Schleifen und effiziente Datentypen.

Häufig gestellte Fragen

Ist die Lektion „Rang und Perzentil innerhalb von Gruppen“ kostenlos?

Ja — der vollständige Text von „Rang und Perzentil innerhalb von Gruppen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Pandas & NumPy Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Rang und Perzentil innerhalb von Gruppen“?

Berechnen Sie mit groupby().rank() Ränge innerhalb von Gruppen und erstellen Sie mit pd.qcut Perzentilklassen für relative Vergleiche. Du übst Pandas & NumPy Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Pandas & NumPy Academy zu starten?

Keine Vorkenntnisse erforderlich. Pandas & NumPy Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Rang und Perzentil innerhalb von Gruppen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Pandas & NumPy Academy-Lektion Code schreiben und ausführen?

Ja. Jede Pandas & NumPy Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Rollende Fenster
  2. Erweiterte Fenster
  3. Exponentiell gewichteter gleitender Mittelwert
  4. Rang und Perzentil innerhalb von Gruppen
← Zurück zu Pandas & NumPy Academy