0Pricing
Pandas & NumPy Academy · Lekcja

pd.merge: złączenia wewnętrzne i zewnętrzne

Połącz dwa obiekty DataFrame według wspólnej kolumny klucza za pomocą złączeń wewnętrznych i zewnętrznych oraz dowiedz się, które wiersze zostaną zachowane lub usunięte.

pd.merge: złączenia wewnętrzne i zewnętrzne to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 2 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 złączenie?

Złączenie łączy dwie ramki danych, dopasowując wiersze na podstawie wspólnej kolumny klucza — to ta sama koncepcja co klauzula JOIN w języku SQL. Pandas implementuje złączenia za pomocą pd.merge(). W przeciwieństwie do pd.concat(), które po prostu układa dane jedna ramka za drugą, pd.merge() inteligentnie dopasowuje wiersze z dwóch różnych tabel na podstawie zgodnych wartości w jednej lub kilku kolumnach.

Wspólna kolumna klucza

Aby scalanie zadziałało, obie ramki danych muszą mieć co najmniej jedną kolumnę ze wspólnymi wartościami — jest to kolumna klucza. Na przykład tabela orders ma kolumnę customer_id, a tabela customers również ma kolumnę customer_id. Scalenie po customer_id dołącza dane klienta do każdego wiersza zamówienia. Gdy obie ramki danych mają kolumnę o tej samej nazwie, należy określić klucz za pomocą parametru on.

import pandas as pd

orders = pd.DataFrame({
    'order_id': [1, 2, 3, 4],
    'customer_id': [101, 102, 101, 103],
    'amount': [250, 80, 320, 150]
})

customers = pd.DataFrame({
    'customer_id': [101, 102, 104],
    'name': ['Alice', 'Bob', 'Diana']
})

Złączenie wewnętrzne: część wspólna obu tabel

Złączenie wewnętrzne (domyślne) zachowuje tylko te wiersze, w których wartość klucza występuje w obu ramkach danych. Wiersze z dowolnej tabeli, dla których nie ma pasującego klucza w drugiej tabeli, są po cichu usuwane. W przykładzie z zamówieniami klienci 103 i 104 nie mają dopasowania w drugiej tabeli, więc ich wiersze są wykluczane z wyniku złączenia wewnętrznego.

# Inner join (default): only matching rows from both
result = pd.merge(orders, customers, on='customer_id', how='inner')
print(result)
#    order_id  customer_id  amount   name
# 0         1          101     250  Alice
# 1         3          101     320  Alice
# 2         2          102      80    Bob
# Order 4 (customer 103) dropped - no match in customers
# Diana (customer 104) dropped - no match in orders

Złączenie zewnętrzne: suma obu tabel

Złączenie zewnętrzne (how='outer') zachowuje wszystkie wiersze z obu ramek danych. Jeśli wiersz nie ma pasującego klucza w drugiej tabeli, brakujące kolumny są wypełniane wartością NaN. Jest to przydatne, gdy chcą Państwo uzyskać pełny obraz obu zbiorów danych, zachowując rekordy, dla których nie znaleziono dopasowania.

result = pd.merge(orders, customers, on='customer_id', how='outer')
print(result)
#    order_id  customer_id  amount   name
# 0       1.0          101   250.0  Alice
# 1       3.0          101   320.0  Alice
# 2       2.0          102    80.0    Bob
# 3       4.0          103   150.0    NaN  <- order with unknown customer
# 4       NaN          104     NaN  Diana  <- customer with no orders

Scalanie kolumn o różnych nazwach

Gdy kolumna klucza ma inną nazwę w każdej ramce danych, należy zamiast on użyć parametrów left_on i right_on. Pandas dopasowuje wiersze, w których left_on w lewej ramce danych jest równe right_on w prawej ramce danych. Obie kolumny klucza pojawiają się w wyniku; później można usunąć jedną z nich jako zbędną.

products = pd.DataFrame({
    'prod_id': [10, 20, 30],
    'name': ['Widget', 'Gadget', 'Doohickey']
})

order_lines = pd.DataFrame({
    'item_id': [10, 10, 20],
    'qty': [3, 1, 5]
})

result = pd.merge(order_lines, products,
                  left_on='item_id', right_on='prod_id')
print(result.drop(columns='prod_id'))
#    item_id  qty    name
# 0       10    3  Widget
# 1       10    1  Widget
# 2       20    5  Gadget

Scalanie po wielu kolumnach

Aby dopasowywać wiersze na podstawie kombinacji kolumn (klucza złożonego), należy przekazać listę do on. Jest to częste, gdy pojedyncza kolumna nie wystarcza do uzyskania unikatowego dopasowania, na przykład przy scalaniu po year i region. Wszystkie wymienione kolumny muszą pasować jednocześnie, aby wiersz został uwzględniony w wyniku.

targets = pd.DataFrame({
    'year': [2023, 2023, 2024],
    'region': ['East', 'West', 'East'],
    'target': [100, 150, 120]
})
actuals = pd.DataFrame({
    'year': [2023, 2024, 2024],
    'region': ['East', 'East', 'West'],
    'actual': [95, 115, 80]
})

result = pd.merge(targets, actuals, on=['year', 'region'], how='inner')
print(result)
#    year region  target  actual
# 0  2023   East     100      95
# 1  2024   East     120     115

Obsługa nakładających się nazw kolumn

Gdy obie ramki danych mają kolumnę o tej samej nazwie (inną niż klucz), Pandas dodaje przyrostki, aby je rozróżnić. Domyślne przyrostki to _x (lewa strona) i _y (prawa strona). Można je dostosować za pomocą parametru suffixes, aby uzyskać bardziej znaczące nazwy i uniknąć niejasności w wyniku.

df_a = pd.DataFrame({'id': [1, 2], 'value': [10, 20]})
df_b = pd.DataFrame({'id': [1, 2], 'value': [100, 200]})

# Default suffixes
print(pd.merge(df_a, df_b, on='id'))
#    id  value_x  value_y

# Custom suffixes
print(pd.merge(df_a, df_b, on='id', suffixes=('_budget', '_actual')))
#    id  value_budget  value_actual

Sprawdzanie nieoczekiwanych duplikatów

Częstym problemem przy scalaniu jest nieoczekiwane zwielokrotnienie wierszy. Jeśli kolumna klucza zawiera zduplikowane wartości w obu ramkach danych, scalanie tworzy iloczyn kartezjański wszystkich pasujących wierszy. Zawsze należy sprawdzić liczbę wierszy po scaleniu: jeśli jest większa, niż oczekiwano, trzeba sprawdzić duplikaty w kolumnie klucza za pomocą df.duplicated(subset=['key']).sum().

# Both tables have duplicate keys -> cartesian product
left = pd.DataFrame({'id': [1, 1], 'val_l': ['a', 'b']})
right = pd.DataFrame({'id': [1, 1], 'val_r': ['x', 'y']})

result = pd.merge(left, right, on='id')
print(len(result))  # 4 rows! (2x2 cartesian product)
print(result)
#    id val_l val_r
# 0   1     a     x
# 1   1     a     y
# 2   1     b     x
# 3   1     b     y

Parametr validate zapewniający bezpieczeństwo

Przekazanie parametru validate pozwala wymusić ograniczenia dotyczące relacji podczas scalania i zgłosić błąd w przypadku ich naruszenia. 'one_to_one' wymaga unikatowych kluczy w obu tabelach, 'one_to_many' wymaga unikatowych kluczy tylko w lewej tabeli, a 'many_to_one' — tylko w prawej. Jest to doskonała praktyka programowania defensywnego, która wcześnie wykrywa problemy z jakością danych.

# Safe merge: validate that customer_id is unique in customers
try:
    result = pd.merge(orders, customers,
                      on='customer_id',
                      how='inner',
                      validate='many_to_one')
    print('Merge OK, shape:', result.shape)
except Exception as e:
    print('Merge error:', e)

Sprawdzanie pokrycia za pomocą indicator

Przekazanie indicator=True dodaje do wyniku kolumnę _merge, która pokazuje, skąd pochodzi każdy wiersz: 'left_only', 'right_only' lub 'both'. Jest to przydatne po złączeniu zewnętrznym do identyfikowania rekordów, dla których znaleziono dopasowanie, i tych, dla których go nie znaleziono. Ułatwia także kontrolę jakości danych przed usunięciem kolumny wskaźnika.

result = pd.merge(orders, customers, on='customer_id',
                  how='outer', indicator=True)
print(result['_merge'].value_counts())
# both           3
# left_only      1  <- orders with no customer record
# right_only     1  <- customers with no orders

# Find unmatched orders
print(result[result['_merge'] == 'left_only'])

Podsumowanie: złączenie wewnętrzne a zewnętrzne

Podsumujmy dwa typy złączeń: złączenie wewnętrzne daje część wspólną — tylko wiersze z pasującymi kluczami w obu ramkach danych. Złączenie zewnętrzne daje sumę — wszystkie wiersze z obu ramek danych, z wartością NaN tam, gdzie nie ma dopasowania. Dla pełnego obrazu: złączenie lewostronne zachowuje wszystkie wiersze z lewej ramki danych, a złączenie prawostronne zachowuje wszystkie wiersze z prawej ramki danych. Zostaną one omówione w następnej lekcji.

# Quick reference
# how='inner'  -> intersection: only matched rows
# how='outer'  -> union: all rows from both, NaN for no match
# how='left'   -> all left rows + matched right rows
# how='right'  -> all right rows + matched left rows

# Most common: inner (default) for enrichment, left for preserving records

Szybkie sprawdzenie

Sprawdź, czy rozumieją Państwo złączenia wewnętrzne i zewnętrzne pd.merge omówione w tej lekcji.

Podsumowanie lekcji

W tej lekcji nauczyli się Państwo, że pd.merge() z how='inner' zachowuje tylko pasujące wiersze z obu ramek danych, a how='outer' zachowuje wszystkie wiersze, używając NaN dla niedopasowanych; parametr on określa wspólny klucz, natomiast left_on/right_on obsługują różne nazwy kolumn; a parametr indicator pomaga sprawdzić, które wiersze zostały dopasowane. Następnie omówimy złączenia lewostronne i prawostronne służące do zachowania wszystkich wierszy z jednej strony.

Często zadawane pytania

Czy lekcja „pd.merge: złączenia wewnętrzne i zewnętrzne” jest bezpłatna?

Tak — pełny tekst „pd.merge: złączenia wewnętrzne i zewnętrzne” 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 „pd.merge: złączenia wewnętrzne i zewnętrzne”?

Połącz dwa obiekty DataFrame według wspólnej kolumny klucza za pomocą złączeń wewnętrznych i zewnętrznych oraz dowiedz się, które wiersze zostaną zachowane lub usunięte. Ć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 2 z 4.

Ile czasu zajmuje lekcja „pd.merge: złączenia wewnętrzne i zewnętrzne”?

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. pd.concat do układania DataFrame
  2. pd.merge: złączenia wewnętrzne i zewnętrzne
  3. Złączenia lewostronne i prawostronne
  4. Łączenie według indeksu
← Powrót do Pandas & NumPy Academy