Dua tabel berbeda jenis sering tersimpan terpisah: satu tabel menyimpan stok gudang, tabel lain menyimpan harga jual. Untuk menghitung nilai persediaan, kita membutuhkan keduanya berdampingan dalam satu tabel. Penyandingan horizontal berbeda dari penumpukan baris: jumlah baris tidak bertambah, yang bertambah adalah kolomnya. Penentu keberhasilan penyandingan adalah index, karena pandas mencocokkan baris lewat label index, bukan lewat posisi. Pada Chapter ini kita mempelajari pd.concat() dengan axis=1, perilakunya ketika label index tidak cocok, serta penyaringan baris dengan join="inner".

Penyandingan Horizontal dengan axis=1 #

Nilai axis=1 mengarahkan pandas bekerja pada sumbu kolom: kolom DataFrame kedua ditempelkan di sisi kanan kolom terakhir DataFrame pertama. Karena penempatan kolom membutuhkan kepastian “baris mana menempel dengan baris mana”, pandas menjajarkan kedua tabel berdasarkan label index. Label yang ada di kedua tabel akan berbagi satu baris hasil. Label yang hanya ada di salah satu tabel tetap dipertahankan pada join="outer" (nilai default), dan kolom pasangannya diisi NaN.

Contoh: Stok dan Harga Berdampingan #

Skrip berikut menyandingkan tabel stok berisi tiga produk dengan tabel harga berisi dua produk. Kedua tabel memakai nama produk sebagai index, dan index tersebut diberi nama produk agar header hasil terbaca jelas.

python
import pandas as pd

stok = pd.DataFrame(
    {"stok": [40, 25, 60]},
    index=pd.Index(["Kopi Gayo", "Teh Melati", "Gula Aren"], name="produk"),
)

harga = pd.DataFrame(
    {"harga": [85000, 32000]},
    index=pd.Index(["Kopi Gayo", "Teh Melati"], name="produk"),
)

sandingan = pd.concat([stok, harga], axis=1)
print(sandingan)
print()
print(sandingan.dtypes)
print()

hanya_cocok = pd.concat([stok, harga], axis=1, join="inner")
print(hanya_cocok)

Output yang Dihasilkan:

text
            stok    harga
produk                   
Kopi Gayo     40  85000.0
Teh Melati    25  32000.0
Gula Aren     60      NaN

stok       int64
harga    float64
dtype: object

            stok  harga
produk                 
Kopi Gayo     40  85000
Teh Melati    25  32000

Mari kita telaah apa yang terjadi pada kode di atas:

  1. Baris 3-6: DataFrame stok dibuat dengan satu kolom stok dan index berupa nama produk; parameter name="produk" memberi nama pada sumbu index.
  2. Baris 8-11: DataFrame harga dibuat dengan pola yang sama, tetapi hanya memuat dua produk.
  3. Baris 13-16: pd.concat([stok, harga], axis=1) menyandingkan keduanya; hasilnya tiga baris dengan dua kolom, dan Gula Aren memperoleh NaN di kolom harga karena tidak ada di tabel harga.
  4. Baris 19-20: join="inner" menyaring hasil sehingga hanya label index yang dimiliki kedua tabel, yaitu Kopi Gayo dan Teh Melati, yang dipertahankan.

Urutan baris pada hasil mengikuti urutan kemunculan label di tabel-tabel sumber: ketiga label stok diproses lebih dulu sesuai urutan tabelnya, karena stok berada lebih awal di dalam list pd.concat(). Perhatikan juga dtypes pada output: kolom harga berubah menjadi float64 padahal isinya angka bulat, karena kolom int64 yang menerima NaN otomatis dipromosikan ke float64.

Menyaring Baris dengan join=“inner” #

Parameter join pada penyandingan horizontal bekerja pada baris, bukan pada kolom. Nilai join="inner" mempertahankan hanya label index yang dimiliki semua tabel sumber; pada contoh kita, label Gula Aren dibuang dan kolom harga kembali bertipe int64 karena tidak ada NaN lagi. Pilihan ini tepat ketika analisis menuntut data lengkap dua arah, misalnya menghitung nilai persediaan yang harus mempunyai stok sekaligus harga tercatat. Sebaliknya, join="outer" dipakai ketika baris tidak lengkap tetap perlu terlihat untuk keperluan audit.

Method pandas.DataFrame.join menyediakan jalan pintas untuk penyandingan berbasis index ini; method tersebut memanggil mekanisme yang sama dan berguna saat satu tabel utama perlu digabung dengan beberapa tabel pendukung sekaligus. Panduan merging menempatkan concat dan join berdampingan sehingga mudah dibandingkan. Penyandingan index menuntut index yang sudah rapi dan bermakna. Pada data nyata, relasi antar tabel biasanya dijaga oleh kolom kunci seperti id_pelanggan. Penggabungan kolom memiliki satu pola lagi: dua versi tabel yang sama dengan lubang di tempat berbeda; menambalnya adalah pekerjaan combine_first() pada Chapter berikutnya, sebelum kita berkenalan dengan pd.merge().