Transformacja i filtrowanie GroupBy
Użyj transform(), aby dodać statystyki na poziomie grupy jako kolumnę, oraz filter(), aby zachować tylko grupy spełniające warunek.
Transformacja i filtrowanie GroupBy to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 4 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.
Poza agregacją
Po opanowaniu agg() naturalnie pojawia się pytanie: co zrobić, jeśli chcą Państwo zachować wszystkie oryginalne wiersze, ale wzbogacić je o statystyki na poziomie grup? Albo zachować tylko grupy spełniające określony warunek? Właśnie do tego służą transform() i filter(). Te dwie metody rozszerzają możliwości GroupBy poza proste podsumowywanie, umożliwiając tworzenie cech i wybieranie danych.
Zrozumienie transform()
transform() stosuje funkcję do każdej grupy i zwraca wynik o takim samym kształcie jak oryginalny DataFrame — po jednej wartości dla każdego oryginalnego wiersza. Wynik dla grupy jest rozgłaszany z powrotem do każdego wiersza należącego do tej grupy. Dzięki temu metoda idealnie nadaje się do dodawania statystyk na poziomie grup jako nowych kolumn bez zmiany liczby wierszy.
import pandas as pd
df = pd.DataFrame({
'dept': ['Eng', 'HR', 'Eng', 'HR', 'Eng'],
'salary': [90000, 60000, 95000, 62000, 88000]
})
# Add a column with each employee's department average salary
df['dept_avg'] = df.groupby('dept')['salary'].transform('mean')
print(df)
# dept salary dept_avg
# 0 Eng 90000 91000.000
# 1 HR 60000 61000.000
# 2 Eng 95000 91000.000
# 3 HR 62000 61000.000
# 4 Eng 88000 91000.000Typowe zastosowania transform()
Typowe zastosowania transform() to: dodawanie średniej grupy w celu normalizacji wartości, dodawanie sumy grupy w celu obliczenia udziału każdego wiersza w całości oraz dodawanie rankingu w grupie w celu sprawdzenia, jak każdy element wypada na tle swojej grupy. Wszystkie te operacje zachowują oryginalny kształt i indeks, dzięki czemu wynik można od razu wykorzystać razem z pierwotnymi kolumnami.
# Percentage of each employee's salary within their department total
df['pct_of_dept'] = (
df['salary'] / df.groupby('dept')['salary'].transform('sum') * 100
).round(1)
print(df[['dept', 'salary', 'pct_of_dept']])
# dept salary pct_of_dept
# Eng 90000 33.1
# HR 60000 49.2
# Eng 95000 34.9Używanie własnej funkcji w transform()
Podobnie jak agg(), transform() przyjmuje dowolny obiekt wywoływalny oprócz nazw zapisanych jako ciągi znaków. Funkcja otrzymuje Series wartości dla jednej grupy i musi zwrócić Series o tej samej długości albo wartość skalarną, która zostanie następnie rozgłoszona. Zwracanie wartości skalarnej jest najczęstszym przypadkiem użycia — zwrócenie Series o innej długości spowoduje błąd.
# Z-score normalisation within each department
def zscore(s):
return (s - s.mean()) / s.std()
df['salary_zscore'] = df.groupby('dept')['salary'].transform(zscore)
print(df[['dept', 'salary', 'salary_zscore']].round(2))
# dept salary salary_zscore
# Eng 90000 -0.51
# HR 60000 -0.71
# Eng 95000 1.03agg() a transform() — porównanie
Najważniejsza różnica jest następująca: agg() zmniejsza liczbę wierszy (jeden wiersz na grupę), natomiast transform() zachowuje liczbę wierszy (jeden wiersz na każdy oryginalny wiersz). Proszę używać agg() do tworzenia tabeli podsumowania, a transform() do dodawania informacji na poziomie grup jako nowej kolumny cech w oryginalnym DataFrame.
g = df.groupby('dept')['salary']
# agg: 2 rows (one per unique dept)
print(g.agg('mean'))
# dept
# Eng 91000.0
# HR 61000.0
# transform: 5 rows (one per original row)
print(g.transform('mean'))
# 0 91000.0
# 1 61000.0
# 2 91000.0
# 3 61000.0
# 4 91000.0Zrozumienie filter()
filter() zachowuje lub odrzuca całe grupy na podstawie funkcji boolowskiej. Przekazują Państwo funkcję, która otrzymuje pod-DataFrame dla jednej grupy i zwraca True (zachowaj grupę) albo False (odrzuć grupę). Wynikiem jest podzbiór oryginalnego DataFrame zawierający wyłącznie wiersze z grup, które przeszły test.
df2 = pd.DataFrame({
'dept': ['Eng', 'HR', 'Eng', 'HR', 'Eng', 'Legal'],
'salary': [90000, 60000, 95000, 62000, 88000, 70000]
})
# Keep only departments with at least 2 employees
big_depts = df2.groupby('dept').filter(lambda g: len(g) >= 2)
print(big_depts)
# dept, salary rows: Eng(3) and HR(2) remain; Legal(1) droppedFiltrowanie według zagregowanej wartości grupy
Bardzo częstym zastosowaniem filter() jest zachowywanie grup, których zagregowana wartość spełnia określony próg. Można na przykład zachować tylko działy, w których średnie wynagrodzenie przekracza ustalony cel, albo tylko kategorie produktów, których łączna sprzedaż przekracza minimum. Pozwala to usunąć grupy o małej liczebności przed dalszą analizą.
# Keep only departments where average salary > 80000
high_paying = df2.groupby('dept').filter(
lambda g: g['salary'].mean() > 80000
)
print(high_paying)
# dept salary
# 0 Eng 90000
# 2 Eng 95000
# 4 Eng 88000
# (HR avg is 61000, filtered out)Łączenie transform() i filter()
Mogą Państwo kolejno zastosować transform() i filter(), aby wzbogacić dane, a następnie je zawęzić. Najpierw proszę użyć filter() do usunięcia nieistotnych grup, a potem zastosować transform() do przefiltrowanego wyniku, aby dodać cechy na poziomie grup. To połączenie daje czysty, bogaty w cechy podzbiór gotowy do modelowania lub raportowania.
# Step 1: keep only large departments
filtered = df2.groupby('dept').filter(lambda g: len(g) >= 2)
# Step 2: add group mean salary to the filtered result
filtered = filtered.copy()
filtered['dept_avg'] = filtered.groupby('dept')['salary'].transform('mean')
print(filtered)transform() do uzupełniania w przód w obrębie grup
transform() jest również przydatna w przypadku funkcji nienumerycznych. Popularny wzorzec polega na uzupełnianiu brakujących wartości w obrębie grupy za pomocą uzupełniania w przód lub mediany grupy, co jest znacznie lepsze niż uzupełnianie globalne. Proszę przekazać funkcję lambda, która wywołuje fillna() na Series grupy; wynik będzie miał ten sam indeks co oryginalny DataFrame.
import numpy as np
df3 = pd.DataFrame({
'dept': ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
'salary': [90000, np.nan, 60000, np.nan, 88000]
})
# Fill NaN with the group mean
df3['salary_filled'] = df3.groupby('dept')['salary'].transform(
lambda s: s.fillna(s.mean())
)
print(df3)Praktyczny wzorzec: pozycja względna
Jednym z użytecznych zastosowań biznesowych jest obliczanie pozycji każdego wiersza względem jego grupy. Łącząc transform() z działaniami arytmetycznymi, można dodać kolumny takie jak: wynagrodzenie pomniejszone o średnią grupy (odchylenie), wynagrodzenie jako część całkowitej sumy grupy albo flaga boolowska określająca, czy dany pracownik zarabia powyżej mediany grupy. Te cechy są niezwykle przydatne w dashboardach i modelach ML.
df['dept_total'] = df.groupby('dept')['salary'].transform('sum')
df['pct_of_total'] = (df['salary'] / df['dept_total'] * 100).round(1)
df['above_avg'] = df['salary'] > df.groupby('dept')['salary'].transform('mean')
print(df[['dept', 'salary', 'pct_of_total', 'above_avg']])Kwestie wydajności
Zarówno transform(), jak i filter() z wbudowanymi funkcjami zapisanymi jako ciągi znaków działają szybko, ponieważ korzystają ze zoptymalizowanych ścieżek wykonania. Jednak po przekazaniu funkcji lambda lub własnej funkcji Python Pandas musi wywołać ją osobno dla każdej grupy, co może być wolne w przypadku danych zawierających wiele grup. Aby uzyskać maksymalną wydajność na dużych zbiorach danych, należy sprawdzić, czy własną logikę można wyrazić za pomocą wbudowanej funkcji zapisanej jako ciąg znaków.
# Slower: custom lambda (called once per group)
df['dept_mean_slow'] = df.groupby('dept')['salary'].transform(lambda s: s.mean())
# Faster: built-in string shortcut (vectorised C path)
df['dept_mean_fast'] = df.groupby('dept')['salary'].transform('mean')
# Both give identical results, but the built-in is significantly fasterSzybkie sprawdzenie
Sprawdź swoje zrozumienie metod GroupBy transform() i filter() omówionych w tej lekcji.
Podsumowanie lekcji
W tej lekcji nauczyli się Państwo, że transform() zwraca statystyki grup rozgłoszone z powrotem do pierwotnej liczby wierszy, dzięki czemu idealnie nadaje się do dodawania cech na poziomie grup; filter() zachowuje lub usuwa całe grupy na podstawie warunku boolowskiego; a połączenie obu metod pozwala tworzyć rozbudowane, przefiltrowane zbiory danych do dalszej analizy. Następnie omówimy łączenie DataFrame za pomocą pd.concat.
Ucz się Python dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 30
- Lekcje
- 120
Często zadawane pytania
Czy lekcja „Transformacja i filtrowanie GroupBy” jest bezpłatna?
Tak — pełny tekst „Transformacja i filtrowanie GroupBy” 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 „Transformacja i filtrowanie GroupBy”?
Użyj transform(), aby dodać statystyki na poziomie grupy jako kolumnę, oraz filter(), aby zachować tylko grupy spełniające warunek. Ć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 4 z 4.
Ile czasu zajmuje lekcja „Transformacja i filtrowanie GroupBy”?
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
- Wzorzec Split-Apply-Combine
- GroupBy z jednym i wieloma kluczami
- Metoda agg()
- Transformacja i filtrowanie GroupBy