0Pricing
Pandas & NumPy Academy · Lekcja

Ranking wartości

Przypisuj rangi wartościom w kolumnach za pomocą rank(), wybieraj metody rozstrzygania remisów i twórz przedziały percentylowe za pomocą pd.cut().

Ranking wartości to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Czym jest ranking?

Ranking przypisuje każdej wartości w Series pozycję na podstawie jej względnej wielkości — rangę 1 dla najmniejszej wartości i rangę n dla największej (lub odwrotnie). W przeciwieństwie do sortowania, które zmienia kolejność wierszy, rank() dodaje obok oryginalnych danych nową kolumnę z pozycjami porządkowymi. Rankingi są używane w tabelach wyników, przy obliczaniu percentyli oraz w niektórych testach statystycznych, które wymagają pozycji porządkowej zamiast wartości bezwzględnych.

import pandas as pd

df = pd.DataFrame({
    'player': ['Alice', 'Bob', 'Carol', 'Dave', 'Eve'],
    'score': [88, 72, 95, 72, 85]
})

df['rank'] = df['score'].rank()
print(df)
#    player  score  rank
# 0   Alice     88   4.0
# 1     Bob     72   1.5   <- tied with Dave
# 2   Carol     95   5.0
# 3    Dave     72   1.5   <- tied with Bob
# 4     Eve     85   3.0

Ranking rosnący i malejący

Domyślnie rank() przypisuje rangę 1 najmniejszej wartości (ranking rosnący). Aby ranga 1 przypadała największej wartości (np. pierwszemu miejscu w zawodach), należy przekazać ascending=False. Odzwierciedla to konwencję „pierwsze miejsce = najwyższy wynik”, stosowaną w sporcie, tabelach wyników i rankingach sprzedaży.

import pandas as pd

df = pd.DataFrame({'score': [70, 95, 85, 60, 90]})

# Rank 1 = highest score
df['competition_rank'] = df['score'].rank(ascending=False)
print(df)
#    score  competition_rank
# 0     70               4.0
# 1     95               1.0
# 2     85               3.0
# 3     60               5.0
# 4     90               2.0

Metody rozstrzygania remisów

Gdy wiele wierszy ma tę samą wartość (remis), parametr method określa sposób przypisywania rang. Dostępne opcje to: 'average' (domyślna — remisujące wiersze otrzymują średnią rangę), 'min' (wszystkie remisujące wiersze otrzymują najniższą rangę), 'max' (wszystkie otrzymują najwyższą rangę), 'first' (wiersz występujący jako pierwszy otrzymuje niższą rangę) oraz 'dense' (po remisie w numeracji rang nie ma luk).

import pandas as pd

s = pd.Series([10, 20, 20, 30])

print('average:', s.rank(method='average').tolist())  # [1.0, 2.5, 2.5, 4.0]
print('min:    ', s.rank(method='min').tolist())      # [1.0, 2.0, 2.0, 4.0]
print('max:    ', s.rank(method='max').tolist())      # [1.0, 3.0, 3.0, 4.0]
print('first:  ', s.rank(method='first').tolist())    # [1.0, 2.0, 3.0, 4.0]
print('dense:  ', s.rank(method='dense').tolist())    # [1.0, 2.0, 2.0, 3.0]

Ranking gęsty: brak luk po remisach

Metoda 'dense' jest szczególnie przydatna, gdy potrzebują Państwo rankingu bez luk. Przy użyciu 'min' dwa wpisy ex aequo na 2. miejscu sprawiają, że następna ranga to 4 (z pominięciem 3). W przypadku 'dense' następna ranga zawsze wynosi 3, dzięki czemu sekwencja pozostaje ciągła. Ranking gęsty jest standardem w funkcji okna SQL DENSE_RANK() i jest często używany w tabelach wyników.

import pandas as pd

df = pd.DataFrame({
    'name': ['A', 'B', 'C', 'D', 'E'],
    'score': [100, 80, 80, 60, 60]
})

df['dense_rank'] = df['score'].rank(method='dense', ascending=False).astype(int)
print(df)
#   name  score  dense_rank
# 0    A    100           1
# 1    B     80           2
# 2    C     80           2  <- same score, same rank
# 3    D     60           3  <- next rank is 3, not 4
# 4    E     60           3

Ranking percentylowy z pct=True

Ustawienie pct=True w rank() normalizuje rangi do zakresu [0, 1], dając rangę percentylową. Wartość z rangą percentylową 0.8 jest wyższa niż 80% wartości w kolumnie. Stosuje się to w finansach (wyniki percentylowe), ocenianiu (percentyle wyników) oraz wykrywaniu wartości odstających.

import pandas as pd

df = pd.DataFrame({'score': [50, 70, 80, 90, 100]})

df['percentile'] = df['score'].rank(pct=True)
print(df)
#    score  percentile
# 0     50         0.2
# 1     70         0.4
# 2     80         0.6
# 3     90         0.8
# 4    100         1.0

Ranking wewnątrz grup

Aby niezależnie obliczać rangi w każdej grupie (np. rangę wynagrodzenia w każdym dziale), należy połączyć groupby() z rank(). Proszę użyć groupby().rank(), które stosuje funkcję rank w każdej grupie i zwraca Series zgodny z indeksem oryginalnego DataFrame — idealne rozwiązanie do dodania kolumny „ranga w grupie”.

import pandas as pd

df = pd.DataFrame({
    'dept': ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
    'name': ['Alice', 'Bob', 'Carol', 'Dave', 'Eve'],
    'salary': [90000, 70000, 55000, 65000, 80000]
})

df['dept_rank'] = df.groupby('dept')['salary'].rank(
    method='dense', ascending=False
).astype(int)
print(df.sort_values(['dept', 'dept_rank']))
#    dept   name  salary  dept_rank
# 0   Eng  Alice   90000          1
# 4   Eng    Eve   80000          2
# 1   Eng    Bob   70000          3
# 3    HR   Dave   65000          1
# 2    HR  Carol   55000          2

pd.cut() dla przedziałów o równej szerokości

pd.cut(series, bins) dzieli ciągłą kolumnę liczbową na przedziały o równej szerokości (koszyki) i przypisuje każdą wartość do odpowiedniego przedziału. Pozwala to przekształcić zmienną ciągłą w zmienną kategorialną, co jest przydatne w histogramach, grupach wiekowych, przedziałach dochodów i wszelkich zadaniach dyskretyzacji. Wynikiem jest Series typu Categorical z etykietami przedziałów.

import pandas as pd

df = pd.DataFrame({'age': [5, 15, 25, 35, 45, 55, 65, 75]})

df['age_group'] = pd.cut(df['age'], bins=[0, 18, 35, 60, 100],
                          labels=['Child', 'Young Adult', 'Middle Age', 'Senior'])
print(df)
#    age    age_group
# 0    5        Child
# 1   15        Child
# 2   25  Young Adult
# 3   35  Young Adult
# 4   45   Middle Age
# 5   55   Middle Age
# 6   65       Senior
# 7   75       Senior

pd.qcut() dla przedziałów o równej liczebności

pd.qcut(series, q) dzieli wartości na przedziały oparte na kwantylach, z których każdy zawiera w przybliżeniu taką samą liczbę obserwacji. W przeciwieństwie do pd.cut() (równa szerokość), pd.qcut() tworzy grupy o równej liczebności — przydatne w segmentacji opartej na percentylach, takiej jak podział na decyle, kwintyle lub kwartyle.

import pandas as pd
import numpy as np

np.random.seed(0)
df = pd.DataFrame({'score': np.random.randint(40, 100, 20)})

# Split into 4 equal-frequency quartiles
df['quartile'] = pd.qcut(df['score'], q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
print(df['quartile'].value_counts().sort_index())
# Q1    5
# Q2    5
# Q3    5
# Q4    5

cut() a qcut() — najważniejsze różnice

Proszę użyć pd.cut(), gdy przedziały mają naturalne znaczenie w danej dziedzinie (np. grupy wiekowe 0–18, 18–35, 35–60) — szerokość przedziałów ma wtedy znaczenie semantyczne. Proszę użyć pd.qcut(), gdy potrzebne są grupy o równej liczebności, niezależnie od położenia granic — na przykład do podziału klientów na górne i dolne kwartyle. Rozkład skośny utworzy bardzo nierówne grupy za pomocą cut(), ale równe grupy za pomocą qcut().

import pandas as pd
import numpy as np

np.random.seed(0)
# Skewed distribution: most values near 0
skewed = pd.Series(np.random.exponential(scale=5, size=100).round())

# cut with equal width: many empty or tiny upper bins
cut_counts = pd.cut(skewed, bins=4).value_counts().sort_index()
print('cut():', cut_counts.values)

# qcut with equal frequency: always 25 per group
qcut_counts = pd.qcut(skewed, q=4).value_counts().sort_index()
print('qcut():', qcut_counts.values)

Dodawanie numeru rangi jako kolumny

Przejrzysty schemat tworzenia tabeli wyników z rankingiem to: posortowanie malejąco, zresetowanie indeksu do wartości zaczynających się od 0, przesunięcie o 1 w celu uzyskania czytelnej dla człowieka numeracji od 1 oraz wyświetlenie rankingu obok oryginalnych danych. Powstaje w ten sposób gotowa do prezentacji tabela wyników bez luk i z czytelnymi numerami rang.

import pandas as pd

df = pd.DataFrame({
    'team': ['Falcons', 'Eagles', 'Hawks', 'Owls'],
    'wins': [12, 9, 12, 7]
})

leaderboard = (
    df
    .sort_values('wins', ascending=False)
    .reset_index(drop=True)
)
leaderboard.index = leaderboard.index + 1
leaderboard.index.name = 'place'
print(leaderboard)

Ranga jako cecha w uczeniu maszynowym

Cechy przekształcone na rangi są przydatne w uczeniu maszynowym, ponieważ są odporne na wartości odstające — bardzo duża lub bardzo mała wartość otrzymuje rangę blisko jednego z krańców, zamiast zniekształcać rozkład cechy. Transformacja rangowa bywa stosowana jako etap wstępnego przetwarzania przed modelami opartymi na drzewach lub wtedy, gdy skala liczbowa nie ma znaczenia, ale istotna jest kolejność względna.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'income': [30000, 50000, 70000, 1_000_000]  # outlier at 1M
})

# Add rank as a feature
df['income_rank'] = df['income'].rank(pct=True)
print(df)
#      income  income_rank
# 0    30000         0.25
# 1    50000         0.50
# 2    70000         0.75
# 3  1000000         1.00
# The outlier has rank 1.0 — extreme but not disproportionate

Szybki test

Sprawdź swoją wiedzę na temat rangowania wartości w Pandas.

Podsumowanie lekcji

W tej lekcji nauczyłeś się, że: rank() przypisuje wartościom pozycje porządkowe, method='dense' eliminuje luki po remisach, pct=True zwraca rangi percentylowe w zakresie [0,1], a groupby().rank() oblicza rangi wewnątrz grup. Używaj pd.cut() do przedziałów o równej szerokości, a pd.qcut() do przedziałów o równej liczebności podczas dyskretyzacji zmiennych ciągłych. W następnej części ustawimy i zresetujemy indeks DataFrame.

Często zadawane pytania

Czy lekcja „Ranking wartości” jest bezpłatna?

Tak — pełny tekst „Ranking wartości” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Ranking wartości”?

Przypisuj rangi wartościom w kolumnach za pomocą rank(), wybieraj metody rozstrzygania remisów i twórz przedziały percentylowe za pomocą pd.cut(). Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?

Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Ranking wartości”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?

Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Sortowanie według wartości kolumn
  2. Sortowanie według indeksu
  3. Ranking wartości
  4. Ustawianie i resetowanie indeksu
← Powrót do Pandas & NumPy Academy