Ana içeriğe geç

Orta13 dk

Birleştirme (merge, join, concat)

Önkoşul:groupby ve pivot

Kanca

Bir sipariş tablon var, bir de müşteri bilgi tablon. Sipariş tablosunda musteri_id=999 var ama bu müşteri, müşteri tablosunda kayıtlı değil (silinmiş hesap olabilir). İki tabloyu birleştirince bu sipariş ne olmalı — kaybolsun mu, yoksa müşteri bilgisi boş kalarak listede dursun mu? Cevap, hangi birleştirme türünü seçtiğine bağlı.

Sezgi

Gerçek veri neredeyse hiç tek bir tabloda durmaz — siparişler bir tabloda, müşteriler başka bir tabloda, ürünler başka bir tabloda olur. merge, iki tabloyu ORTAK BİR SÜTUNA (anahtar) göre yan yana birleştirir — SQL’deki JOIN ile aynı mantık. concat ise iki tabloyu ÜST ÜSTE (aynı sütunlarla) yığar — örneğin ocak ve şubat siparişlerini tek bir tabloda toplamak için.

merge’ün en kritik kararı how parametresidir: inner, sadece HER İKİ tabloda da bulunan anahtarları tutar; left, sol tablonun TAMAMINI korur, eşleşmeyen sağ taraf bilgisi boş (NaN) kalır.

Mekanizma

İki tablo kuralım — siparişlerin bazı müşteri numaraları, müşteri tablosunda yok:

İki ayrı tablo

# İki AYRI tablo: siparişler ve müşteriler. Bazı sipariş müşterileri, müşteri
# tablosunda YOK (örn. silinmiş hesap) — gerçek dünyada sık karşılaşılan bir durum.
siparisler = pd.DataFrame({
    "siparis_no": [f"S{i}" for i in range(1, 9)],
    "musteri_id": [101, 102, 103, 101, 104, 999, 102, 998],  # 999 ve 998 müşteri tablosunda yok
    "tutar": [149.9, 89.5, 320.0, 45.0, 210.75, 60.0, 180.0, 99.0],
})

musteriler = pd.DataFrame({
    "musteri_id": [101, 102, 103, 104],
    "segment": ["Sadık", "Yeni", "Sadık", "Yeni"],
    "sehir": ["İstanbul", "Ankara", "İzmir", "Bursa"],
})

print("Siparişler:", siparisler.shape)
print("Müşteriler:", musteriler.shape)
Siparişler: (8, 3)
Müşteriler: (4, 3)

Şimdi iki farklı how ile birleştirelim:

inner vs left join

# INNER JOIN: sadece HER İKİ tabloda da olan musteri_id'ler kalır.
ic_birlesim = siparisler.merge(musteriler, on="musteri_id", how="inner")
print(f"\nInner join sonucu: {len(ic_birlesim)} satır (eşleşmeyenler düştü)")
print(ic_birlesim)

# LEFT JOIN: siparişlerin TAMAMI kalır, eşleşmeyen müşteri bilgisi NaN olur.
sol_birlesim = siparisler.merge(musteriler, on="musteri_id", how="left")
print(f"\nLeft join sonucu: {len(sol_birlesim)} satır (hiçbir sipariş kaybolmadı)")
print(sol_birlesim[["siparis_no", "musteri_id", "segment"]])

Inner join sonucu: 6 satır (eşleşmeyenler düştü)
  siparis_no  musteri_id   tutar segment     sehir
0         S1         101  149.90   Sadık  İstanbul
1         S2         102   89.50    Yeni    Ankara
2         S3         103  320.00   Sadık     İzmir
3         S4         101   45.00   Sadık  İstanbul
4         S5         104  210.75    Yeni     Bursa
5         S7         102  180.00    Yeni    Ankara

Left join sonucu: 8 satır (hiçbir sipariş kaybolmadı)
  siparis_no  musteri_id segment
0         S1         101   Sadık
1         S2         102    Yeni
2         S3         103   Sadık
3         S4         101   Sadık
4         S5         104    Yeni
5         S6         999     NaN
6         S7         102    Yeni
7         S8         998     NaN

inner join’de 8 siparişten 6’sı kaldı — 999 ve 998 numaralı müşterilerin siparişleri (S6, S8) düştü, çünkü bu müşteriler musteriler tablosunda yok. left join’de ise 8 siparişin TAMAMI kaldı, sadece eşleşmeyen satırlarda segment sütunu NaN oldu.

Çoğu kişi “merge her zaman satır kaybetmez” ya da tam tersini, “merge her zaman tüm satırları korur” sanır. Değil, çünkü ikisi de how parametresine bağlı bir seçimdir — inner bilinçli olarak eşleşmeyenleri atar, left bilinçli olarak korur. Hangisini seçtiğin, “kaç sipariş kaybettim” sorusunun cevabını doğrudan değiştirir.

Matematik

merge türleri ve concat
TürNe tutulur
innerSadece HER İKİ tabloda da bulunan anahtarlar
leftSol tablonun TÜM satırları; sağdan eşleşmeyen yerler NaN
rightSağ tablonun TÜM satırları; soldan eşleşmeyen yerler NaN
outerHER İKİ tablonun TÜM satırları; eşleşmeyen her iki yönde de NaN
concatAnahtar araması yapmaz — tabloları doğrudan üst üste (veya yan yana) yığar

concat, merge’den kavramsal olarak farklıdır: merge “bu satır, o satırla nasıl eşleşiyor” sorusunu sorarken, concat sadece “bu tabloları birbirine ekle” der — aynı sütun yapısına sahip parçaları (örn. farklı ayların verisi) birleştirmek için idealdir.

Kod

concat ile iki ayrı ayın sipariş verisini birleştirelim:

concat ile üst üste birleştirme

# concat: iki tabloyu ÜST ÜSTE (aynı sütunlarla) birleştirmek — örn. iki ayrı ayın verisi.
ocak = pd.DataFrame({"siparis_no": ["S101", "S102"], "tutar": [120.0, 85.0], "ay": "Ocak"})
subat = pd.DataFrame({"siparis_no": ["S201", "S202"], "tutar": [95.0, 310.0], "ay": "Şubat"})

tum_yil = pd.concat([ocak, subat], ignore_index=True)
print(f"\nOcak: {len(ocak)} satır, Şubat: {len(subat)} satır, birleşim: {len(tum_yil)} satır")
print(tum_yil)

Ocak: 2 satır, Şubat: 2 satır, birleşim: 4 satır
  siparis_no  tutar     ay
0       S101  120.0   Ocak
1       S102   85.0   Ocak
2       S201   95.0  Şubat
3       S202  310.0  Şubat
Sadık ve Yeni müşteri segmentlerinin toplam ciro karşılaştırmasını gösteren çubuk grafik.
left join sonrası, eşleşmeyen (segment bilgisi olmayan) siparişleri çıkarıp geri kalanı segmentlere göre özetledik.

Nerede işe yarar

Birleştirme, gerçek dünyadaki neredeyse her veri analizinin ilk adımlarından biridir:

  • Çoklu tablo veritabanları. Siparişler, müşteriler, ürünler gibi ayrı tablolarda tutulan ilişkisel verileri tek bir analiz tablosuna toplamak.
  • Zaman bazlı veri birleştirme. Farklı dönemlerden (aylık, yıllık) gelen dosyaları tek bir veri setinde toplamak (concat).
  • Veri zenginleştirme. Bir ana tabloya, referans tablolardan (ülke kodları, kategori adları) ek bilgi eklemek.

Bu 3 hatayı yaparsın:

  1. how parametresini düşünmeden varsayılanı (inner) kullanıp sessizce veri kaybetmek.
  2. Birleştirme sonrası satır sayısını kontrol etmemek — beklenmedik bir artış, anahtar sütununda tekrarlanan değerler olduğunu gösterebilir.
  3. concat ile merge’ü karıştırmak — concat anahtar araması yapmaz, sadece sütun yapısı uyan tabloları üst üste yığar.

Kendini test et

1. `inner` join ile `left` join arasındaki temel fark nedir?
  1. Aralarında fark yoktur
  2. inner sadece her iki tabloda da eşleşen anahtarları tutar, left sol tablonun tüm satırlarını korur (doğru cevap)
  3. left her zaman daha az satır döndürür
  4. inner sadece sayısal anahtarlarda çalışır

Neden: inner join eşleşmeyen satırları atar; left join sol tablonun tamamını korur ve eşleşmeyen sağ taraf bilgisini NaN ile doldurur.

2. Notebook örneğinde inner join sonrası neden 8 değil 6 satır kaldı?
  1. Hata oluştu
  2. 999 ve 998 numaralı müşteriler musteriler tablosunda olmadığı için o siparişler düştü (doğru cevap)
  3. pandas rastgele satır siler
  4. concat kullanıldığı için

Neden: inner join sadece HER İKİ tabloda da bulunan anahtarları tutar; 999 ve 998 müşteri tablosunda olmadığı için onlara ait siparişler sonuçtan düştü.

3. concat ile merge arasındaki temel fark nedir?
  1. Aynı işlevi görürler
  2. concat anahtar eşleştirmesi yapmadan tabloları üst üste yığar, merge ortak bir sütuna göre eşleştirir (doğru cevap)
  3. concat sadece sayısal verilerde çalışır
  4. merge sadece iki tablo ile çalışır, concat sınırsız

Neden: merge bir anahtar sütununa göre satırları eşleştirirken, concat hiçbir eşleştirme yapmadan tabloları doğrudan birbirine ekler (genelde aynı sütun yapısındaki parçaları birleştirmek için).

Özet

Özet

  • merge, iki tabloyu ortak bir anahtar sütuna göre yan yana birleştirir — SQL JOIN mantığıyla.
  • inner join sadece eşleşen anahtarları tutar; left join sol tablonun tamamını korur.
  • concat, aynı sütun yapısındaki tabloları anahtar araması yapmadan üst üste yığar.
  • how parametresini bilinçli seçmek, birleştirme sonrası kaç satırın kaldığını doğrudan belirler.
  • Birleştirme sonrası satır sayısını her zaman kontrol etmek, beklenmedik veri kaybını veya çoğalmasını erken yakalar.
Sonraki adım: Eksik veri stratejileri →