Celovit vodnik za združevanje in spajanje DataFrame-ov v Python Pandas. Razložene so različne strategije (notranje, zunanje, leve, desne) s primeri za globalno analizo.
Združevanje Python Pandas: Obvladovanje strategij spajanja DataFrame-ov za analizo podatkov
Manipulacija podatkov je ključnega pomena pri analizi podatkov, in knjižnica Pandas v Pythonu ponuja zmogljiva orodja za ta namen. Med temi orodji sta združevanje in spajanje DataFrame-ov bistveni operaciji za kombiniranje naborov podatkov na podlagi skupnih stolpcev ali indeksov. Ta celovit vodnik raziskuje različne strategije spajanja DataFrame-ov v Pandas, kar vam omogoča, da učinkovito kombinirate in analizirate podatke iz različnih virov.
Razumevanje združevanja in spajanja DataFrame-ov
Združevanje in spajanje DataFrame-ov vključujeta kombiniranje dveh ali več DataFrame-ov v en sam DataFrame na podlagi skupnega stolpca ali indeksa. Glavna razlika med `merge` in `join` je v tem, da je `merge` funkcija knjižnice Pandas in običajno spaja DataFrame-e na stolpcih, medtem ko je `join` metoda DataFrame-a, ki spaja DataFrame-e predvsem na indeksih, čeprav se lahko uporablja tudi s stolpci.
Ključni koncepti
- DataFrames: Dvodimenzionalne označene podatkovne strukture s stolpci potencialno različnih tipov.
- Skupni stolpci/indeksi: Stolpci ali indeksi, ki si delijo isto ime in podatkovni tip med DataFrame-i in služijo kot osnova za združevanje/spajanje.
- Tipi spajanj: Različne strategije za obravnavo neujemanih vrstic med postopkom združevanja/spajanja, vključno z notranjim, zunanjim, levim in desnim spajanjem.
Združevanje DataFrame-ov s funkcijo `pd.merge()`
Funkcija `pd.merge()` je glavno orodje za združevanje DataFrame-ov na podlagi stolpcev. Ponuja prilagodljiv način za kombiniranje podatkov na podlagi enega ali več skupnih stolpcev.
Sintaksa
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
Parametri
- left: Levi DataFrame za združitev.
- right: Desni DataFrame za združitev.
- how: Tip združitve, ki se izvede ('inner', 'outer', 'left', 'right'). Privzeta vrednost je 'inner'.
- on: Ime stolpca(ev) za spajanje. Ti morajo biti prisotni v obeh DataFrame-ih.
- left_on: Ime stolpca(ev) v levem DataFrame-u za uporabo kot ključi za spajanje.
- right_on: Ime stolpca(ev) v desnem DataFrame-u za uporabo kot ključi za spajanje.
- left_index: Če je True, uporabi indeks iz levega DataFrame-a kot ključ(e) za spajanje.
- right_index: Če je True, uporabi indeks iz desnega DataFrame-a kot ključ(e) za spajanje.
- sort: Razvrsti rezultantni DataFrame leksikografsko po ključih za spajanje. Privzeta vrednost je False.
- suffixes: Terka nizov pripon, ki se uporabijo za prekrivajoča se imena stolpcev. Privzeta vrednost je ('_x', '_y').
- copy: Če je False, se izogiba kopiranju podatkov v nov DataFrame, kjer je to mogoče. Privzeta vrednost je True.
- indicator: Če je True, doda stolpec z imenom '_merge', ki označuje vir vsake vrstice.
- validate: Preveri, ali je združitev določenega tipa. "one_to_one", "one_to_many", "many_to_one", "many_to_many".
Pojasnjeni tipi spajanj
Parameter `how` v funkciji `pd.merge()` določa tip izvedenega spajanja. Različni tipi spajanj obravnavajo neujemanje vrstic na različne načine.
Notranje spajanje (Inner Join)
Notranje spajanje vrne samo vrstice, ki imajo ujemajoče se vrednosti v obeh DataFrame-ih na podlagi ključev za spajanje. Vrstice z neujemajočimi se vrednostmi so izključene iz rezultata.
Primer:
Razmislite o dveh DataFrame-ih:
import pandas as pd
# DataFrame 1: Customer Orders
df_orders = pd.DataFrame({
'order_id': [1, 2, 3, 4, 5],
'customer_id': [101, 102, 103, 104, 105],
'product_id': [1, 2, 1, 3, 2],
'quantity': [2, 1, 3, 1, 2]
})
# DataFrame 2: Customer Information
df_customers = pd.DataFrame({
'customer_id': [101, 102, 103, 106],
'customer_name': ['Alice', 'Bob', 'Charlie', 'David'],
'country': ['USA', 'Canada', 'UK', 'Australia']
})
# Inner Join
df_inner = pd.merge(df_orders, df_customers, on='customer_id', how='inner')
print(df_inner)
Izhod:
order_id customer_id product_id quantity customer_name country
0 1 101 1 2 Alice USA
1 2 102 2 1 Bob Canada
2 3 103 1 3 Charlie UK
V tem primeru notranje spajanje kombinira DataFrame-a `df_orders` in `df_customers` na podlagi stolpca `customer_id`. V rezultat so vključene samo stranke, ki so oddale naročila. Stranka 'David' (customer_id 106) je izključena, ker nima nobenih naročil.
Zunanje spajanje (Full Outer Join)
Zunanje spajanje vrne vse vrstice iz obeh DataFrame-ov, vključno z neujemajočimi se vrsticami. Če vrstica nima ujemanja v drugem DataFrame-u, bodo ustrezni stolpci vsebovali vrednosti `NaN` (ni število).
Primer:
# Outer Join
df_outer = pd.merge(df_orders, df_customers, on='customer_id', how='outer')
print(df_outer)
Izhod:
order_id customer_id product_id quantity customer_name country
0 1.0 101 1.0 2.0 Alice USA
1 2.0 102 2.0 1.0 Bob Canada
2 3.0 103 1.0 3.0 Charlie UK
3 4.0 104 3.0 1.0 NaN NaN
4 5.0 105 2.0 2.0 NaN NaN
5 NaN 106 NaN NaN David Australia
Zunanje spajanje vključuje vse stranke in vsa naročila. Stranke 104 in 105 imajo naročila, vendar nimajo podatkov o strankah, stranka 106 pa ima podatke o strankah, vendar nima naročil. Manjkajoče vrednosti so predstavljene kot `NaN`.
Levo spajanje (Left Join)
Levo spajanje vrne vse vrstice iz levega DataFrame-a in ujemajoče se vrstice iz desnega DataFrame-a. Če vrstica v levem DataFrame-u nima ujemanja v desnem DataFrame-u, bodo ustrezni stolpci iz desnega DataFrame-a vsebovali vrednosti `NaN`.
Primer:
# Left Join
df_left = pd.merge(df_orders, df_customers, on='customer_id', how='left')
print(df_left)
Izhod:
order_id customer_id product_id quantity customer_name country
0 1 101 1 2 Alice USA
1 2 102 2 1 Bob Canada
2 3 103 1 3 Charlie UK
3 4 104 3 1 NaN NaN
4 5 105 2 2 NaN NaN
Levo spajanje vključuje vsa naročila iz `df_orders`. Stranke 104 in 105 imajo naročila, vendar nimajo podatkov o strankah, zato so stolpci `customer_name` in `country` za ta naročila `NaN`.
Desno spajanje (Right Join)
Desno spajanje vrne vse vrstice iz desnega DataFrame-a in ujemajoče se vrstice iz levega DataFrame-a. Če vrstica v desnem DataFrame-u nima ujemanja v levem DataFrame-u, bodo ustrezni stolpci iz levega DataFrame-a vsebovali vrednosti `NaN`.
Primer:
# Right Join
df_right = pd.merge(df_orders, df_customers, on='customer_id', how='right')
print(df_right)
Izhod:
order_id customer_id product_id quantity customer_name country
0 1.0 101 1.0 2.0 Alice USA
1 2.0 102 2.0 1.0 Bob Canada
2 3.0 103 1.0 3.0 Charlie UK
3 NaN 106 NaN NaN David Australia
Desno spajanje vključuje vse stranke iz `df_customers`. Stranka 106 ima podatke o strankah, vendar nima naročil, zato so stolpci `order_id`, `product_id` in `quantity` za to stranko `NaN`.
Spajanje DataFrame-ov z metodo `df.join()`
Metoda `df.join()` se primarno uporablja za spajanje DataFrame-ov na podlagi njihovih indeksov. Uporablja se lahko tudi za spajanje na stolpcih, vendar je za spajanje na podlagi stolpcev običajno bolj priročno uporabiti `pd.merge()`.
Sintaksa
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)
Parametri
- other: Drugi DataFrame za spajanje.
- on: Ime stolpca za spajanje. Mora biti podano, če indeks ni uporabljen kot ključ za spajanje.
- how: Kako obravnavati operacijo levega in desnega nabora. Privzeta vrednost je 'left'.
- lsuffix: Pripona, ki se uporabi iz levega DataFrame-a za prepisovanje prekrivajočih se imen stolpcev.
- rsuffix: Pripona, ki se uporabi iz desnega DataFrame-a za prepisovanje prekrivajočih se imen stolpcev.
- sort: Razvrsti rezultantni DataFrame leksikografsko po ključih za spajanje. Privzeta vrednost je False.
Spajanje na indeksu
Pri spajanju na indeksu se parameter `on` ne uporablja.
Primer:
# DataFrame 1: Customer Orders with Customer ID as Index
df_orders_index = df_orders.set_index('customer_id')
# DataFrame 2: Customer Information with Customer ID as Index
df_customers_index = df_customers.set_index('customer_id')
# Join on Index (Left Join)
df_join_index = df_orders_index.join(df_customers_index, how='left')
print(df_join_index)
Izhod:
order_id product_id quantity customer_name country
customer_id
101 1 1 2 Alice USA
102 2 2 1 Bob Canada
103 3 1 3 Charlie UK
104 4 3 1 NaN NaN
105 5 2 2 NaN NaN
V tem primeru je metoda `join()` uporabljena za izvedbo levega spajanja na indeksu (`customer_id`). Rezultat je podoben levemu spajanju z uporabo `pd.merge()`, vendar je spajanje na podlagi indeksa in ne stolpca.
Spajanje na stolpcu
Za spajanje na stolpcu z uporabo `df.join()` morate določiti parameter `on`.
Primer:
# Joining on a column
df_join_column = df_orders.join(df_customers.set_index('customer_id'), on='customer_id', how='left')
print(df_join_column)
Izhod:
order_id customer_id product_id quantity customer_name country
0 1 101 1 2 Alice USA
1 2 102 2 1 Bob Canada
2 3 103 1 3 Charlie UK
3 4 104 3 1 NaN NaN
4 5 105 2 2 NaN NaN
Ta primer prikazuje spajanje `df_orders` z `df_customers` z uporabo stolpca `customer_id`. Upoštevajte, da je `customer_id` nastavljen kot indeks v `df_customers` pred izvedbo spajanja.
Obravnava prekrivajočih se stolpcev
Pri združevanju ali spajanju DataFrame-ov je pogosto naleteti na prekrivajoča se imena stolpcev (stolpci z istim imenom v obeh DataFrame-ih). Pandas ponuja parameter `suffixes` v funkciji `pd.merge()` ter parametra `lsuffix` in `rsuffix` v metodi `df.join()` za obravnavo teh situacij.
Uporaba `suffixes` v `pd.merge()`
Parameter `suffixes` vam omogoča, da določite pripone, ki bodo dodane prekrivajočim se imenom stolpcev, da jih boste razlikovali.
Primer:
# DataFrame 1: Product Information
df_products1 = pd.DataFrame({
'product_id': [1, 2, 3],
'product_name': ['Product A', 'Product B', 'Product C'],
'price': [10, 20, 15]
})
# DataFrame 2: Product Information (with potentially updated prices)
df_products2 = pd.DataFrame({
'product_id': [1, 2, 4],
'product_name': ['Product A', 'Product B', 'Product D'],
'price': [12, 18, 25]
})
# Merge with suffixes
df_merged_suffixes = pd.merge(df_products1, df_products2, on='product_id', suffixes=('_old', '_new'))
print(df_merged_suffixes)
Izhod:
product_id product_name_old price_old product_name_new price_new
0 1 Product A 10 Product A 12
1 2 Product B 20 Product B 18
V tem primeru sta stolpca `product_name` in `price` prisotna v obeh DataFrame-ih. Parameter `suffixes` doda priponi `_old` in `_new` za razlikovanje stolpcev iz levega oziroma desnega DataFrame-a.
Uporaba `lsuffix` in `rsuffix` v `df.join()`
Parametra `lsuffix` in `rsuffix` zagotavljata podobno funkcionalnost za `df.join()`. `lsuffix` se doda prekrivajočim se stolpcem levega DataFrame-a, `rsuffix` pa desnega DataFrame-a.
Primer:
# Join with lsuffix and rsuffix
df_products1_index = df_products1.set_index('product_id')
df_products2_index = df_products2.set_index('product_id')
df_joined_suffixes = df_products1_index.join(df_products2_index, lsuffix='_old', rsuffix='_new', how='outer')
print(df_joined_suffixes)
Izhod:
product_name_old price_old product_name_new price_new
product_id
1 Product A 10.0 Product A 12.0
2 Product B 20.0 Product B 18.0
3 Product C 15.0 NaN NaN
4 NaN NaN Product D 25.0
Praktični primeri in primeri uporabe
Združevanje in spajanje DataFrame-ov se pogosto uporabljata v različnih scenarijih analize podatkov. Tukaj je nekaj praktičnih primerov:
Kombiniranje prodajnih podatkov z informacijami o izdelkih
Pogost primer uporabe je kombiniranje prodajnih podatkov z informacijami o izdelkih. Predpostavimo, da imate DataFrame, ki vsebuje prodajne transakcije, in drug DataFrame, ki vsebuje podrobnosti o izdelkih. Te DataFrame-e lahko združite, da obogatite prodajne podatke z informacijami o izdelkih.
Primer:
# Sales Transactions Data
df_sales = pd.DataFrame({
'transaction_id': [1, 2, 3, 4, 5],
'product_id': [101, 102, 103, 101, 104],
'quantity': [2, 1, 3, 1, 2],
'sales_date': ['2023-01-15', '2023-02-20', '2023-03-10', '2023-04-05', '2023-05-01']
})
# Product Information Data
df_products = pd.DataFrame({
'product_id': [101, 102, 103, 104],
'product_name': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'category': ['Electronics', 'Electronics', 'Electronics', 'Electronics'],
'price': [1200, 25, 75, 300]
})
# Merge Sales Data with Product Information
df_sales_enriched = pd.merge(df_sales, df_products, on='product_id', how='left')
print(df_sales_enriched)
Izhod:
transaction_id product_id quantity sales_date product_name category price
0 1 101 2 2023-01-15 Laptop Electronics 1200
1 2 102 1 2023-02-20 Mouse Electronics 25
2 3 103 3 2023-03-10 Keyboard Electronics 75
3 4 101 1 2023-04-05 Laptop Electronics 1200
4 5 104 2 2023-05-01 Monitor Electronics 300
Nastali DataFrame `df_sales_enriched` vsebuje prodajne transakcije skupaj z ustreznimi informacijami o izdelkih, kar omogoča podrobnejšo analizo prodajnih trendov in uspešnosti izdelkov.
Kombiniranje podatkov o strankah z demografskimi informacijami
Drug pogost primer uporabe je kombiniranje podatkov o strankah z demografskimi informacijami. To omogoča analizo vedenja strank na podlagi demografskih dejavnikov.
Primer:
# Customer Data
df_customers = pd.DataFrame({
'customer_id': [1, 2, 3, 4, 5],
'customer_name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'city': ['New York', 'London', 'Tokyo', 'Sydney', 'Berlin']
})
# Demographic Information Data
df_demographics = pd.DataFrame({
'city': ['New York', 'London', 'Tokyo', 'Sydney', 'Berlin'],
'population': [8419000, 8982000, 13960000, 5312000, 3769000],
'average_income': [75000, 65000, 85000, 90000, 55000]
})
# Merge Customer Data with Demographic Information
df_customer_demographics = pd.merge(df_customers, df_demographics, on='city', how='left')
print(df_customer_demographics)
Izhod:
customer_id customer_name city population average_income
0 1 Alice New York 8419000 75000
1 2 Bob London 8982000 65000
2 3 Charlie Tokyo 13960000 85000
3 4 David Sydney 5312000 90000
4 5 Eve Berlin 3769000 55000
Nastali DataFrame `df_customer_demographics` vsebuje podatke o strankah skupaj z demografskimi informacijami za njihova mesta, kar omogoča analizo vedenja strank na podlagi demografskih podatkov mest.
Analiza podatkov globalne dobavne verige
Združevanje v Pandas je dragoceno za analizo podatkov globalne dobavne verige, kjer so informacije pogosto razpršene po več tabelah. Na primer, povezovanje podatkov o dobaviteljih, informacij o pošiljkah in prodajnih številk lahko razkrije ozka grla in optimizira logistiko.
Primer:
# Supplier Data
df_suppliers = pd.DataFrame({
'supplier_id': [1, 2, 3],
'supplier_name': ['GlobalTech', 'EuroParts', 'AsiaSource'],
'location': ['Taiwan', 'Germany', 'China']
})
# Shipping Data
df_shipments = pd.DataFrame({
'shipment_id': [101, 102, 103, 104],
'supplier_id': [1, 2, 3, 1],
'destination': ['USA', 'Canada', 'Australia', 'Japan'],
'shipment_date': ['2023-01-10', '2023-02-15', '2023-03-20', '2023-04-25']
})
# Merge Supplier and Shipment Data
df_supply_chain = pd.merge(df_shipments, df_suppliers, on='supplier_id', how='left')
print(df_supply_chain)
Izhod:
shipment_id supplier_id destination shipment_date supplier_name location
0 101 1 USA 2023-01-10 GlobalTech Taiwan
1 102 2 Canada 2023-02-15 EuroParts Germany
2 103 3 Australia 2023-03-20 AsiaSource China
3 104 1 Japan 2023-04-25 GlobalTech Taiwan
Napredne tehnike združevanja
Združevanje na več stolpcih
DataFrame-e lahko združite na podlagi več stolpcev tako, da parametru `on` posredujete seznam imen stolpcev.
Primer:
# DataFrame 1
df1 = pd.DataFrame({
'product_id': [1, 1, 2, 2],
'color': ['red', 'blue', 'red', 'blue'],
'quantity': [10, 15, 20, 25]
})
# DataFrame 2
df2 = pd.DataFrame({
'product_id': [1, 1, 2, 2],
'color': ['red', 'blue', 'red', 'blue'],
'price': [5, 7, 8, 10]
})
# Merge on multiple columns
df_merged_multiple = pd.merge(df1, df2, on=['product_id', 'color'], how='inner')
print(df_merged_multiple)
Izhod:
product_id color quantity price
0 1 red 10 5
1 1 blue 15 7
2 2 red 20 8
3 2 blue 25 10
Združevanje z različnimi imeni stolpcev
Če imajo spajalni stolpci različna imena v dveh DataFrame-ih, lahko uporabite parametra `left_on` in `right_on` za določitev imen stolpcev, ki se uporabijo za združevanje.
Primer:
# DataFrame 1
df1 = pd.DataFrame({
'product_id': [1, 2, 3],
'product_name': ['Product A', 'Product B', 'Product C']
})
# DataFrame 2
df2 = pd.DataFrame({
'id': [1, 2, 4],
'price': [10, 20, 25]
})
# Merge with different column names
df_merged_different = pd.merge(df1, df2, left_on='product_id', right_on='id', how='left')
print(df_merged_different)
Izhod:
product_id product_name id price
0 1 Product A 1.0 10.0
1 2 Product B 2.0 20.0
2 3 Product C NaN NaN
Uporaba `indicator` za analizo združevanja
Parameter `indicator` v funkciji `pd.merge()` doda stolpec z imenom `_merge` v rezultantni DataFrame, ki označuje vir vsake vrstice. To je uporabno za razumevanje, katere vrstice so se ujemale in katere ne.
Primer:
# Merge with indicator
df_merged_indicator = pd.merge(df_orders, df_customers, on='customer_id', how='outer', indicator=True)
print(df_merged_indicator)
Izhod:
order_id customer_id product_id quantity customer_name country _merge
0 1.0 101 1.0 2.0 Alice USA both
1 2.0 102 2.0 1.0 Bob Canada both
2 3.0 103 1.0 3.0 Charlie UK both
3 4.0 104 3.0 1.0 NaN NaN left_only
4 5.0 105 2.0 2.0 NaN NaN left_only
5 NaN 106 NaN NaN David Australia right_only
Stolpec `_merge` označuje, ali vrstica prihaja iz obeh DataFrame-ov (`both`), samo iz levega DataFrame-a (`left_only`) ali samo iz desnega DataFrame-a (`right_only`).
Potrjevanje tipov združevanja
Parameter `validate` zagotavlja, da je operacija združevanja usklajena s pričakovanimi tipi razmerij med DataFrame-i (npr. 'ena_na_ena', 'ena_na_mnogo'). To pomaga preprečiti nedoslednosti in napake v podatkih.
Primer:
# Example with one-to-one validation
df_users = pd.DataFrame({
'user_id': [1, 2, 3],
'username': ['john_doe', 'jane_smith', 'peter_jones']
})
df_profiles = pd.DataFrame({
'user_id': [1, 2, 3],
'profile_description': ['Software Engineer', 'Data Scientist', 'Project Manager']
})
# Performing a one-to-one merge with validation
merged_df = pd.merge(df_users, df_profiles, on='user_id', validate='one_to_one')
print(merged_df)
Če združevanje krši določeno validacijo (npr. razmerje mnogo-na-ena, ko je določeno 'ena_na_ena'), bo sprožena napaka `MergeError`, ki vas opozori na potencialne težave z integriteto podatkov.
Razmisleki o zmogljivosti
Združevanje in spajanje DataFrame-ov je lahko računsko drago, zlasti za velike nabore podatkov. Tukaj je nekaj nasvetov za izboljšanje zmogljivosti:
- Uporabite ustrezen tip spajanja: Izbira pravilnega tipa spajanja lahko bistveno vpliva na zmogljivost. Na primer, če potrebujete samo ujemajoče se vrstice, uporabite notranje spajanje.
- Indeksirajte spajalne stolpce: Indeksiranje spajalnih stolpcev lahko pospeši postopek združevanja.
- Uporabite ustrezne podatkovne tipe: Zagotovite, da imajo spajalni stolpci združljive podatkovne tipe.
- Izogibajte se nepotrebnim kopijam: Nastavite `copy=False` v funkcijah `pd.merge()` in `df.join()`, da se izognete ustvarjanju nepotrebnih kopij podatkov.
Zaključek
Združevanje in spajanje DataFrame-ov sta temelji operaciji pri analizi podatkov. Z razumevanjem različnih tipov in tehnik spajanja lahko učinkovito kombinirate in analizirate podatke iz različnih virov, s čimer odkrijete dragocene vpoglede in spodbudite informirano odločanje. Od kombiniranja prodajnih podatkov z informacijami o izdelkih do analize globalnih dobavnih verig – obvladovanje teh tehnik vam bo omogočilo, da se z zaupanjem lotite kompleksnih nalog manipulacije podatkov. Ne pozabite upoštevati vplivov na zmogljivost pri delu z velikimi nabori podatkov in izkoristite napredne funkcije, kot sta parametra `indicator` in `validate` za robustnejšo in vpoglednejšo analizo.