merge: Join Gaya SQL

Join bergaya SQL dengan merge: how inner, left, right, dan outer beserta hasilnya.

Daftar isi

pd.merge menggabungkan dua DataFrame dengan mencocokkan nilai pada kolom kunci, mekanisme yang setara dengan JOIN pada SQL. Topik ini mendemokan empat nilai parameter how, yaitu inner, left, right, dan outer, pada data mini yang sama sehingga perbedaan jumlah barisnya terlihat nyata, dilengkapi tabel pemetaan ke sintaks SQL, penanganan nama kolom ganda dengan suffixes, serta daftar kesalahan yang sering terjadi. Setelah topik ini selesai, jenis join dapat dipilih secara sadar sesuai baris yang ingin dipertahankan, bukan mengandalkan nilai bawaannya.

Dua tabel yang akan digabung#

Data relasional biasanya tersebar di beberapa tabel yang terhubung melalui satu kolom kunci. Penggabungan berbasis kunci semacam ini dikenal sebagai join, dan pd.merge adalah wujudnya di pandas. Tabel pertama adalah log pembacaan sensor yang memuat satu baris per pencatatan, sedangkan tabel kedua adalah meta sensor yang memuat satu baris per ruang beserta model dan tanggal kalibrasinya. Kedua tabel berbagi kolom kunci ruang, dengan dua kejanggalan yang disengaja, yaitu sensor Gudang yang belum terdaftar pada meta dan ruang Lobi yang terdaftar tetapi tidak memiliki sensor. Jalankan blok berikut, kemudian amati kedua tabelnya.

python Contoh: log pembacaan dan tabel meta sensor
import pandas as pd

log_mini = pd.DataFrame({
    "ruang": ["Lab A", "Lab B", "Ruang Arsip", "Lab A", "Lab B", "Lab A", "Ruang Arsip", "Gudang"],
    "suhu_c": [23.4, 24.1, 22.8, 24.6, 23.9, 25.0, 23.1, 21.7],
    "lembap_pct": [58.2, 61.3, 63.8, 60.4, 62.7, 57.9, 64.5, 55.3],
})
sensor_meta = pd.DataFrame({
    "ruang": ["Lab A", "Lab B", "Ruang Arsip", "Lobi"],
    "model": ["T-100", "T-100", "T-200", "T-300"],
    "tanggal_kalibrasi": pd.to_datetime(["2025-12-01", "2025-12-10", "2025-11-20", "2025-10-05"]),
})
log_mini.to_csv("log_merge.csv", index=False)  # disimpan agar blok berikutnya cukup membaca berkas ini
sensor_meta.to_csv("meta_merge.csv", index=False)
print(log_mini)
print(sensor_meta)
text Keluaran
         ruang  suhu_c  lembap_pct
0        Lab A    23.4        58.2
1        Lab B    24.1        61.3
2  Ruang Arsip    22.8        63.8
3        Lab A    24.6        60.4
4        Lab B    23.9        62.7
5        Lab A    25.0        57.9
6  Ruang Arsip    23.1        64.5
7       Gudang    21.7        55.3
         ruang  model tanggal_kalibrasi
0        Lab A  T-100        2025-12-01
1        Lab B  T-100        2025-12-10
2  Ruang Arsip  T-200        2025-11-20
3         Lobi  T-300        2025-10-05

Satu ruang muncul berkali-kali di log, sedangkan di meta setiap ruang hanya muncul sekali. Bentuk hubungan seperti ini disebut banyak-ke-satu dan lazim dijumpai pada data log. Jumlah baris hasil join ditentukan oleh jumlah kecocokan kunci per baris, sehingga empat nilai how berikut didemokan pada kedua tabel yang sama persis untuk membuat perbedaannya terlihat.

Empat nilai how dan padanannya di SQL#

Parameter how menentukan baris mana yang dipertahankan ketika kunci tidak ditemukan di kedua tabel. Diagram berikut merangkum keempat pilihannya pada dua tabel A dan B yang saling beririsan.

innerleftrightouterABirisan A dan BABseluruh AABseluruh BABA dan B
Empat jenis join pada dua tabel A dan B

Nilai how="inner" hanya mempertahankan kunci yang tersedia di kedua tabel dan merupakan padanan INNER JOIN pada SQL. Jalankan blok berikut pada log dan meta yang sama.

python Contoh: how inner
import pandas as pd

log_mini = pd.read_csv("log_merge.csv")
sensor_meta = pd.read_csv("meta_merge.csv", parse_dates=["tanggal_kalibrasi"])
hasil_inner = pd.merge(log_mini, sensor_meta, on="ruang", how="inner")
print(len(hasil_inner))
print(hasil_inner)
text Keluaran
7
         ruang  suhu_c  lembap_pct  model tanggal_kalibrasi
0        Lab A    23.4        58.2  T-100        2025-12-01
1        Lab B    24.1        61.3  T-100        2025-12-10
2  Ruang Arsip    22.8        63.8  T-200        2025-11-20
3        Lab A    24.6        60.4  T-100        2025-12-01
4        Lab B    23.9        62.7  T-100        2025-12-10
5        Lab A    25.0        57.9  T-100        2025-12-01
6  Ruang Arsip    23.1        64.5  T-200        2025-11-20

Tujuh baris berhasil dicocokkan, sedangkan baris Gudang hilang karena kuncinya tidak ada di meta. Baris Lab A muncul tiga kali karena ketiga pembacaannya masing-masing menemukan pasangan pada baris meta yang sama. Perilaku penggandaan inilah yang membedakan join dari pencocokan satu lawan satu.

Tabel berikut memetakan setiap nilai how ke padanannya di SQL.

Parameter howPadanan SQLBaris yang dipertahankan
how="inner"INNER JOINhanya kunci yang ada di kedua tabel
how="left"LEFT JOINseluruh baris tabel kiri
how="right"RIGHT JOINseluruh baris tabel kanan
how="outer"FULL OUTER JOINgabungan seluruh baris kedua tabel

Nilai how="left" mempertahankan seluruh baris tabel kiri sebagaimana LEFT JOIN. Blok berikut mengeksekusinya.

python Contoh: how left
import pandas as pd

log_mini = pd.read_csv("log_merge.csv")
sensor_meta = pd.read_csv("meta_merge.csv", parse_dates=["tanggal_kalibrasi"])
hasil_left = pd.merge(log_mini, sensor_meta, on="ruang", how="left")
print(len(hasil_left))
print(hasil_left)
text Keluaran
8
         ruang  suhu_c  lembap_pct  model tanggal_kalibrasi
0        Lab A    23.4        58.2  T-100        2025-12-01
1        Lab B    24.1        61.3  T-100        2025-12-10
2  Ruang Arsip    22.8        63.8  T-200        2025-11-20
3        Lab A    24.6        60.4  T-100        2025-12-01
4        Lab B    23.9        62.7  T-100        2025-12-10
5        Lab A    25.0        57.9  T-100        2025-12-01
6  Ruang Arsip    23.1        64.5  T-200        2025-11-20
7       Gudang    21.7        55.3    NaN               NaT

Seluruh delapan baris log dipertahankan, dan baris Gudang tetap hadir dengan model berisi NaN serta tanggal_kalibrasi berisi NaT. Ruang Lobi yang hanya ada di tabel kanan tidak muncul sama sekali. Pilihan ini tepat ketika log adalah data utama dan meta hanya pelengkap keterangan.

Nilai how="right" mempertahankan seluruh baris tabel kanan, sedangkan how="outer" mempertahankan gabungan seluruh baris kedua tabel sebagaimana FULL OUTER JOIN. Blok berikut mengeksekusi keduanya secara berurutan.

python Contoh: how right
import pandas as pd

log_mini = pd.read_csv("log_merge.csv")
sensor_meta = pd.read_csv("meta_merge.csv", parse_dates=["tanggal_kalibrasi"])
hasil_right = pd.merge(log_mini, sensor_meta, on="ruang", how="right")
print(len(hasil_right))
print(hasil_right)
text Keluaran
8
         ruang  suhu_c  lembap_pct  model tanggal_kalibrasi
0        Lab A    23.4        58.2  T-100        2025-12-01
1        Lab A    24.6        60.4  T-100        2025-12-01
2        Lab A    25.0        57.9  T-100        2025-12-01
3        Lab B    24.1        61.3  T-100        2025-12-10
4        Lab B    23.9        62.7  T-100        2025-12-10
5  Ruang Arsip    22.8        63.8  T-200        2025-11-20
6  Ruang Arsip    23.1        64.5  T-200        2025-11-20
7         Lobi     NaN         NaN  T-300        2025-10-05

Pada how="right", Lobi kini muncul dengan kolom log berisi NaN, sedangkan Gudang yang hanya ada di kiri hilang, dan hasilnya tetap delapan baris. Kombinasi tabel kanan yang unik dengan tabel kiri yang berulang membuat Lab A tampil tiga kali.

python Contoh: how outer
import pandas as pd

log_mini = pd.read_csv("log_merge.csv")
sensor_meta = pd.read_csv("meta_merge.csv", parse_dates=["tanggal_kalibrasi"])
hasil_outer = pd.merge(log_mini, sensor_meta, on="ruang", how="outer")
print(len(hasil_outer))
print(hasil_outer)
text Keluaran
9
         ruang  suhu_c  lembap_pct  model tanggal_kalibrasi
0       Gudang    21.7        55.3    NaN               NaT
1        Lab A    23.4        58.2  T-100        2025-12-01
2        Lab A    24.6        60.4  T-100        2025-12-01
3        Lab A    25.0        57.9  T-100        2025-12-01
4        Lab B    24.1        61.3  T-100        2025-12-10
5        Lab B    23.9        62.7  T-100        2025-12-10
6         Lobi     NaN         NaN  T-300        2025-10-05
7  Ruang Arsip    22.8        63.8  T-200        2025-11-20
8  Ruang Arsip    23.1        64.5  T-200        2025-11-20

Pada how="outer", hasil membengkak menjadi sembilan baris yang memuat Gudang sekaligus Lobi, masing-masing dengan NaN pada sisi yang tidak memiliki pasangan. Hasilnya terurut berdasarkan nilai kunci. Outer join berguna untuk mengaudit kecocokan dua sumber data karena baris yang tidak cocok tidak pernah hilang dari hasil.

Nama kolom yang sama dan suffixes#

Apabila kedua tabel memuat nama kolom yang sama selain kolom kuncinya, pd.merge memberi akhiran otomatis _x untuk tabel kiri dan _y untuk tabel kanan. Akhiran bawaan itu sah tetapi tidak informatif karena tidak mengatakan kolom mana yang berasal dari tabel mana. Parameter suffixes menggantinya dengan akhiran pilihan sendiri, dan kebiasaan yang baik adalah akhiran yang menyebut asal tabelnya. Blok berikut menambahkan kolom petugas pada kedua tabel untuk menunjukkan kedua bentuk akhiran tersebut.

python Contoh: suffixes pada kolom yang sama
import pandas as pd

log_mini = pd.read_csv("log_merge.csv")
sensor_meta = pd.read_csv("meta_merge.csv", parse_dates=["tanggal_kalibrasi"])
log_petugas = log_mini.assign(petugas=["Dewi", "Ali", "Ali", "Dewi", "Budi", "Citra", "Ali", "Budi"])
meta_petugas = sensor_meta.assign(petugas=["Ali", "Budi", "Citra", "Dewi"])
hasil_s = pd.merge(log_petugas, meta_petugas, on="ruang")
print(hasil_s.columns.tolist())
print(hasil_s[["ruang", "petugas_x", "petugas_y"]].head(3))
hasil_s2 = pd.merge(log_petugas, meta_petugas, on="ruang", suffixes=("_log", "_meta"))
print(hasil_s2[["ruang", "petugas_log", "petugas_meta"]].head(3))
text Keluaran
['ruang', 'suhu_c', 'lembap_pct', 'petugas_x', 'model', 'tanggal_kalibrasi', 'petugas_y']
         ruang petugas_x petugas_y
0        Lab A      Dewi       Ali
1        Lab B       Ali      Budi
2  Ruang Arsip       Ali     Citra
         ruang petugas_log petugas_meta
0        Lab A        Dewi          Ali
1        Lab B         Ali         Budi
2  Ruang Arsip         Ali        Citra

Keluaran pertama memperlihatkan petugas_x dan petugas_y yang asalnya harus ditebak, sedangkan keluaran kedua menampilkan petugas_log dan petugas_meta yang langsung menjelaskan sumbernya. Isi kedua kolom memang berbeda karena satu milik baris pencatatan dan satu milik ruangannya. Biasakan menamai akhiran sesuai peran tabel agar hasil join tetap terbaca tanpa membuka data aslinya.

Kesalahan umum#

Kesalahan pada merge jarang tampak sebagai error, melainkan sebagai jumlah baris yang tidak sesuai harapan. Kesalahan berikut paling sering ditemui beserta perbaikannya.

  • Menjalankan pd.merge tanpa parameter how. Nilai bawaannya inner, sehingga baris yang kuncinya tidak ditemukan di kedua tabel dibuang tanpa pesan error, misalnya delapan baris log berubah menjadi tujuh. Isi how secara eksplisit pada setiap panggilan dan periksa len hasilnya.
  • Mengira merge selalu menghasilkan baris sebanyak tabel kiri. Jumlah baris mengikuti jumlah kecocokan kunci, sehingga satu baris kiri dapat hilang atau berlipat. Bandingkan len sebelum dan sesudah merge sebagai kebiasaan pemeriksaan.
  • Membiarkan nama kolom _x dan _y pada kode akhir. Ganti dengan suffixes yang menyebut asal tabel agar kolom hasil mudah dibaca.

Ringkasan#

  • pd.merge mencocokkan dua tabel pada kolom kunci melalui on dan setara dengan JOIN pada SQL, yaitu inner ke INNER JOIN, left ke LEFT JOIN, right ke RIGHT JOIN, dan outer ke FULL OUTER JOIN.
  • how="inner" adalah nilai bawaan, sehingga baris dapat hilang diam-diam bila how tidak diisi.
  • Baris berlipat sesuai jumlah kecocokan kunci, dan kolom yang namanya sama diberi akhiran yang diatur melalui suffixes.

Referensi#