Python Pandas: Left Join, Right Join, Inner Join, Outer Join ve Self Join ile Veri Birleştirme

Enes Eren
7 min readFeb 17, 2023

--

Left Join: Solda Birleşme

Right Join: Sağda Birleşme

Inner Join: Ortak Birleşme

Outer Join: Ayrık Birleşme

Self Join: Yarı Birleşme

Sağda ve Solda birleşmeler sizin “merge” metodunu kullanırken “how” değişkenine verdiğiniz değere göre değişir. “Solda Birleşme” sağ tabloyla eşleşen satırlarla birlikte sol tablodaki bütün satırları döner. “Sağda Birleşme” ise sol tabloyla eşleyen satırlarla birlikte sağ tablodaki bütun satırları döner. Yani bu işlemin sonucunda olarak elde edeceğiniz tablo, burada nerede birleştiğine göre büyük ölçüde değişir.

“how” değişkenine bir değer vermezseniz varsayılan olarak “inner” değerini alır, bunu buradaki yazımda da gördüğümüz gibi “inner” ile birlikte ortak kümede kalan veriler birleşiyordu.

Başlamadan önce kullanacağımız paketleri ve veri setlerini içe aktaralım.

import pandas as pd

movies = pd.read_csv("./movies.csv")
financials = pd.read_csv("./financials.csv")

1. Solda Birleşme

Bir birleştirme işlemi için her iki tablonun da ortak bir sütunda aynı endeks değerlerini alabileceği bir sütun belirlememiz gerekir. Bu bazen birçok sütun da olabilir.

print(movies.head())
print(financials.head())

id title popularity release_date
0 257 Oliver Twist 20.416 2005-09-23
1 14290 Better Luck Tomorrow 3.877 2002-01-12
2 38365 Grown Ups 38.864 2010-06-24
3 9672 Infamous 3.681 2006-11-16
4 12819 Alpha and Omega 12.301 2010-09-17

id budget revenue
0 19995 237000000 2.788e+09
1 285 300000000 9.610e+08
2 206647 245000000 8.807e+08
3 49026 250000000 1.085e+09
4 49529 260000000 2.841e+08

“id” sütununu endeks olarak belirleyebiliriz.

Birleşmeden önceki satır ve sütun sayılarına bir bakalım.

print(movies.shape)
print(financials.shape)

(4803, 4)
(3229, 3)
movies_financials = movies.merge(financials, on="id", how="left")

Birleşmeden sonraki satır ve sütun sayılarına bakalım.

print(movies_financials.shape)

(4803, 6)

Burada iki tabloyu sol tabloda birleştirdik. Sağ tabloyla eşleşen “id”lerin sütunları sol tabloda eşleştiği satırlara ek sütun olarak geldi.

Fakat burada bir sorun var. “financials” veri setimizde 3229 satır var. Birleşme işlemi yapıldıktan sonra “movies” veri setindeki 4803 satırın sadece 3229 satırına ek sütun eklendi ve bu sütunlar veriyle dolduruldu. 4803 — 3229 kadar satıra da EK sütun eklendi ama veri eklenmedi.

number_of_missing_fin = movies_financials['budget'].isnull().sum()

print(number_of_missing_fin)

# 1574

Burada olan şey, solda birleşme yöntemiyle bir birleştirme işlemi gerçekleştirdik. Solda birleşme, bizim sol tabloda bir veri kaybı istemeyip sağdaki tablodan da alabileceğimiz veriyi almaktır. Bizim sol tablomuz burada “movies” veri setiydi. Görüldüğü üzere onun satır ve sütun sayısında bir azalma meydana gelmedi. Sol tabloyu korumuş olduk. Ama sağ tabloyla birleştirerek sağ tablodaki verileri sol tabloda eşleşensatırlara ekledik.

Bunun ortak birleşmeden farkı ise, ortak birleşme ortak kümede kalan satırların birleşmesi olarak yorumlanabilir.

Solda birleşme ile gerçekleşen satır ve sütun değişimi;

(4803, 4)
(3229, 3)

(4803, 6)

Bu 1574 satırda eksik veri olacak ama onun karşılığında 3229 satıra ek veri getirmiş olacağız.

Ortak birleşme ile gerçekleşen satır ve sütun değişimi;

movies_financials = movies.merge(financials, on='id', how='inner')

print(movies_financials.shape)

(3229, 6)

Ortak kümede olmayan değerleri saf dışı bırakıyor.

2. Sağda Birleşme

Aksiyon ve Bilim Kurgu filmleri olmak üzere iki farklı veri setimiz var. Bunlardan bazı Bilim Kurgu filmleri ayrıca Aksiyon olarak sınıflandırılmış. Bu veri setlerini birleştirip hangisinin sadece Bilim Kurgu olduğunu bulup “movies” veri setiyle birleştirmemiz gerekiyor.

action_movies = pd.read_csv("./action_movies.csv")
scifi_movies= pd.read_csv("./scifi_movies.csv")

Veri setlerine bir göz atalım.

print(action_movies.head())
print(scifi_movies.head())

movie_id genre
3 11 Action
14 18 Action
25 22 Action
26 24 Action
42 58 Action

movie_id genre
2 11 Science Fiction
17 18 Science Fiction
20 19 Science Fiction
38 38 Science Fiction
49 62 Science Fiction

Satır ve sütun sayılarına bakalım.

print(action_movies.shape)
print(scifi_movies.shape)

(1154, 2)
(535, 2)

“movie_id” sütunu üzerinde sağda birleşme yapalım.

action_scifi = action_movies.merge(scifi_movies,
on='movie_id',
how='right',
suffixes=('_act','_sci'))

print(action_scifi.head())

movie_id genre_act genre_sci
0 11 Action Science Fiction
1 18 Action Science Fiction
2 19 NaN Science Fiction
3 38 NaN Science Fiction
4 62 NaN Science Fiction

Satır ve sütun sayısına bakalım.

print(action_scifi.shape)

(535, 3)

Burada sağdaki tabloyu koruyarak sol tablonun sütunları sağ tabloda eşleştiği satırlara gelmiş oldu. Böylece aynı “movie_id”ye sahip filmleri yani hem Aksiyon hem de Bilim Kurgu olan filmleri bulduk.

Fakat burada şöyle bir problem oluştu. Her bir satır için bir yerine birden çok kategori sütunu ekledik. Aksiyon filmlerinde hem aksiyon hem de bilim kurgu kategorisi, bilim kurgu filmlerinde ise hem bilim kurgu hem de aksiyon kategorisi olmuş oldu.

Sadece Aksiyon veya sadece Bilim Kurgu olan filmlerin diğer kategorisi null olarak atanmış oldu.

scifi_only = action_scifi[action_scifi["genre_act"].isnull()]

print(scifi_only)

movie_id genre_act genre_sci
2 19 NaN Science Fiction
3 38 NaN Science Fiction
4 62 NaN Science Fiction
5 68 NaN Science Fiction
6 74 NaN Science Fiction
.. ... ... ...
529 333371 NaN Science Fiction
530 335866 NaN Science Fiction
531 347548 NaN Science Fiction
532 360188 NaN Science Fiction
534 371690 NaN Science Fiction

[258 rows x 3 columns]

DataFrame nesnelerinde “null” değerler “NaN” olarak gösterilmektedir.

3. Ortak Birleşme

Başta belirttiğimiz üzere amacımız sadece Bilim Kurgu olan filmleri bulmaktı. “genre_act” yani Aksiyon kategorisi null olan değerler Bilim Kurgudur varsayımıyla veri setimizi filtreledik. Bunu ortak birleşme ile “movies” veri setine ekleyebiliriz.

movies_and_scifi_only = movies.merge(scifi_only,
left_on="id",
right_on="movie_id",
how="inner")

print(movies_and_scifi_only.head())
print(movies_and_scifi_only.shape)

id title popularity release_date movie_id genre_act genre_sci
0 18841 The Lost Skeleton of Cadavra 1.681 2001-09-12 18841 NaN Science Fiction
1 26672 The Thief and the Cobbler 2.439 1993-09-23 26672 NaN Science Fiction
2 15301 Twilight Zone: The Movie 12.903 1983-06-24 15301 NaN Science Fiction
3 8452 The 6th Day 18.447 2000-11-17 8452 NaN Science Fiction
4 1649 Bill & Ted's Bogus Journey 11.350 1991-07-19 1649 NaN Science Fiction

(258, 7)

3. Ayrık Birleşme

Ayrık Birleşme, ortak kümede olmayan değerlerin birleştirilmesidir. Yani sağ tabloda ve sol tabloda birbiriyle eşleşmeyen satırları birleştirir.

“iron_1_actors” ve “iron_1_actors” adında iki adet veri setimiz var. Bunlar Iron Man 1 ve 2 filmlerinin oyuncu adlarını içeren veri setleridir. Burada hem ilk hem de ikinci filmde oynayan oyuncular olmakla birlikte bizim amacımız sadece tek filmde oynamış oyuncuları bulmak.

iron_1_actors = pd.read_csv("./iron_1_actors.csv")
iron_2_actors = pd.read_csv("./iron_2_actors.csv")

Veri setlerine bir göz atalım.

print(iron_1_actors.head())
print(iron_2_actors.head())

character id name
3 Yinsen 17857 Shaun Toub
4 Virginia "Pepper" Potts 12052 Gwyneth Paltrow
2 Obadiah Stane / Iron Monger 1229 Jeff Bridges
1 War Machine 18288 Terrence Howard
7 Christine Everhart 57451 Leslie Bibb

character id name
4 Ivan Vanko / Whiplash 2295 Mickey Rourke
3 Natalie Rushman / Natasha Romanoff / Black Widow 1245 Scarlett Johansson
5 Justin Hammer 6807 Sam Rockwell
6 Director Nick Fury 2231 Samuel L. Jackson
1 Virginia "Pepper" Potts 12052 Gwyneth Paltrow

Biçimlerine göz atalım.

print(iron_1_actors.shape)
print(iron_2_actors.shape)

(87, 3)
(115, 3)

Veri setlerini birleştirelim.

iron_1_and_2 = iron_1_actors.merge(iron_2_actors,
on="id",
how="outer",
suffixes=("_1", "_2"))

print(iron_1_and_2.head())
print(iron_2_actors.shape)

character_1 id name_1 character_2 name_2
0 Virginia "Pepper" Potts 12052 Gwyneth Paltrow Virginia "Pepper" Potts Gwyneth Paltrow
1 Christine Everhart 57451 Leslie Bibb Christine Everhart Leslie Bibb
2 Tony Stark / Iron Man 3223 Robert Downey Jr. Tony Stark / Iron Man Robert Downey Jr.
3 Agent Phil Coulson 9048 Clark Gregg Agent Phil Coulson Clark Gregg
4 J.A.R.V.I.S. (voice) 6162 Paul Bettany J.A.R.V.I.S. (voice) Paul Bettany

(115, 3)

Sadece tek filmde oynayanları bulmak için en az bir “name” sütununda null değeri olanları filtreleyebiliriz.

m = ((iron_1_and_2['name_1'].isnull()) | 
(iron_1_and_2['name_2'].isnull()))

print(iron_1_and_2[m].head())
print(iron_1_and_2[m].shape)

character_1 id name_1 character_2 name_2
0 Yinsen 17857 Shaun Toub NaN NaN
2 Obadiah Stane / Iron Monger 1229 Jeff Bridges NaN NaN
3 War Machine 18288 Terrence Howard NaN NaN
5 Raza 57452 Faran Tahir NaN NaN
8 Abu Bakaar 173810 Sayed Badreya NaN NaN

(180, 5)

4. Yarı Birleşme

Yarı birleşme, tabloyu kendisiyle birleştirmektir.

Veri setimizi içe aktaralım.

crews = pd.read_csv("./crews.csv")

print(crews.head())
print(crews.shape)

id job name
0 19995 Editor Stephen E. Rivkin
2 19995 Sound Designer Christopher Boyes
4 19995 Casting Mali Finn
6 19995 Director James Cameron
7 19995 Writer James Cameron

(42502, 3)

“crews” adında bir veri setimiz var. Set ekibiyle ilgili bilgileri içeriyor. Amacımız her bir film için yönetmeni ve ekibi listeyelen bir tablo oluşturmak.

crews_self_merged = crews.merge(crews, on="id", suffixes=("_dir","_crew"))

print(crews_self_merged.head())

id job_dir name_dir job_crew name_crew
0 19995 Editor Stephen E. Rivkin Editor Stephen E. Rivkin
1 19995 Editor Stephen E. Rivkin Sound Designer Christopher Boyes
2 19995 Editor Stephen E. Rivkin Casting Mali Finn
3 19995 Editor Stephen E. Rivkin Director James Cameron
4 19995 Editor Stephen E. Rivkin Writer James Cameron

Veri setini yönetmen olan ve yönetmen olmayan olarak filtreleyelim.

boolean_filter = ((crews_self_merged['job_dir'] == "Director") & 
(crews_self_merged['job_crew'] != "Director"))

direct_crews = crews_self_merged[boolean_filter]

print(direct_crews.head())

id job_dir name_dir job_crew name_crew
156 19995 Director James Cameron Editor Stephen E. Rivkin
157 19995 Director James Cameron Sound Designer Christopher Boyes
158 19995 Director James Cameron Casting Mali Finn
160 19995 Director James Cameron Writer James Cameron
161 19995 Director James Cameron Set Designer Richard F. Mays

Böylece aynı filmde çalışan yönetmen ve set ekiplerini görebiliriz.

5. Endeks’te Birleşme

Varsayılan olarak bir DataFrame nesnesinin endeksleri satırların sıra numarasıdır. “on” değişkenine verdiğimiz sütunu önceden endeks olarak belirleyip daha sonra “on” değişkenine sütunu verirsek endeksimiz verdiğimiz sütun ile değişmiş olur.

Veri setlerini içe aktarırken endeks belirleyebiliriz.

movies = pd.read_csv("./movies.csv", index_col="id")
ratings = pd.read_csv("./ratings.csv", index_col="id")

Tabloları birleştirme;

movies_ratings = movies.merge(ratings, on="id")

print(movies_ratings.head())

title popularity release_date vote_average vote_count
id
257 Oliver Twist 20.416 2005-09-23 6.7 274.0
14290 Better Luck Tomorrow 3.877 2002-01-12 6.5 27.0
38365 Grown Ups 38.864 2010-06-24 6.0 1705.0
9672 Infamous 3.681 2006-11-16 6.4 60.0
12819 Alpha and Omega 12.301 2010-09-17 5.3 124.0

Baktığımız zaman endekste birleşmenin aslında normal bir birleşmeden farkı yok.

Son

Kullanılan Veri Setleri: Movies, Financials, Actors, Crews, Ratings.

Veri Setleri DataCamp üzerinden alınmıştır.

Beni Linkedin ve Github üzerinden takip edebilirsiniz.

--

--