Data pada pekerjaan nyata jarang datang sebagai satu tabel utuh. Laporan penjualan Januari tersimpan di satu file, laporan Februari di file lain, atau data setiap cabang diekspor secara terpisah oleh sistem kasir. Sebelum bisa dianalisis, tabel-tabel tersebut perlu disatukan menjadi satu DataFrame. Pandas menyediakan fungsi pd.concat() untuk tugas penggabungan ini: fungsi tersebut menerima daftar DataFrame dan menyusunnya menjadi satu tabel. Pada Chapter ini kita mempelajari cara kerja dasar pd.concat(), parameter ignore_index untuk merapikan index, dan parameter join untuk mengatur perlakuan kolom yang berbeda.

Mekanisme Dasar pd.concat() #

Fungsi pd.concat() menerima satu argumen wajib berupa list berisi DataFrame yang ingin digabungkan; halaman pandas.concat merinci seluruh parameter yang tersedia. Secara default, pandas menumpuk objek-objek tersebut secara vertikal: baris DataFrame kedua ditempelkan di bawah baris terakhir DataFrame pertama. Arah penumpukan dikendalikan parameter axis, dan nilai default axis=0 berarti penumpukan baris. Selama menumpuk, pandas tidak mengganti index lama; setiap baris membawa index dari tabel asalnya. Perilaku ini terlihat jelas pada contoh berikut dan menjadi kebingungan yang paling sering dialami pemula.

Contoh Pertama: Menumpuk Dua Tabel #

Kita mulai dari skenario toko yang menyimpan penjualan dalam dua tabel: tabel januari berisi tiga produk, sedangkan tabel maret berisi dua produk dengan satu kolom tambahan bernama cabang. Skrip berikut menggabungkan keduanya dengan tiga cara sekaligus agar perbedaannya langsung terlihat.

python
import pandas as pd

januari = pd.DataFrame({
    "produk": ["Kopi Gayo", "Teh Melati", "Gula Aren"],
    "unit": [12, 30, 25],
})

maret = pd.DataFrame({
    "produk": ["Teh Melati", "Kopi Gayo"],
    "unit": [18, 40],
    "cabang": ["Bandung", "Jakarta"],
})

gabungan = pd.concat([januari, maret])
print(gabungan)
print()

rapikan = pd.concat([januari, maret], ignore_index=True)
print(rapikan)
print()

hanya_umum = pd.concat([januari, maret], join="inner")
print(hanya_umum)

Output yang Dihasilkan:

text
       produk  unit   cabang
0   Kopi Gayo    12      NaN
1  Teh Melati    30      NaN
2   Gula Aren    25      NaN
0  Teh Melati    18  Bandung
1   Kopi Gayo    40  Jakarta

       produk  unit   cabang
0   Kopi Gayo    12      NaN
1  Teh Melati    30      NaN
2   Gula Aren    25      NaN
3  Teh Melati    18  Bandung
4   Kopi Gayo    40  Jakarta

       produk  unit
0   Kopi Gayo    12
1  Teh Melati    30
2   Gula Aren    25
0  Teh Melati    18
1   Kopi Gayo    40

Mari kita telaah apa yang terjadi pada kode di atas:

  1. Baris 3-6: DataFrame januari dibuat dengan dua kolom, yaitu produk bertipe str dan unit bertipe int64.
  2. Baris 8-12: DataFrame maret dibuat dengan satu kolom tambahan cabang yang tidak dimiliki januari.
  3. Baris 14-15: pd.concat([januari, maret]) menumpuk kedua tabel; hasilnya lima baris dengan index 0, 1, 0, 1 karena index asli kedua tabel dipertahankan apa adanya.
  4. Baris 18-19: pemanggilan kedua menambahkan ignore_index=True, sehingga pandas membuang index lama dan menyusun index baru 0 sampai 4.
  5. Baris 22-23: pemanggilan ketiga menambahkan join="inner", sehingga hanya kolom yang dimiliki kedua tabel, yaitu produk dan unit, yang dipertahankan; kolom cabang tidak muncul.

Merapikan Index dengan ignore_index #

Perhatikan tabel pertama pada output: label index berurutan 0, 1, 0, 1 karena kedua tabel asal sama-sama memakai index bawaan RangeIndex. Label ganda semacam ini membahayakan analisis lanjutan. Seleksi berbasis label seperti gabungan.loc[0] akan mengembalikan dua baris sekaligus, dan method yang mengandalkan keunikan index dapat memberikan hasil yang tidak terduga. Parameter ignore_index=True menyelesaikan masalah tersebut: pandas membuang semua label lama dan menyusun RangeIndex baru dari nol. Isi datanya tidak berubah sama sekali; yang diganti hanya label barisnya.

Memilih Kolom dengan join=“inner” #

Parameter join mengatur kolom apa yang muncul ketika kolom tabel-tabel sumber tidak sama. Nilai default join="outer" mempertahankan gabungan semua kolom; kolom yang tidak ada di salah satu tabel diisi NaN, seperti kolom cabang pada tiga baris pertama tabel kedua. Nilai join="inner" bekerja sebaliknya: hanya kolom yang dimiliki semua tabel yang dipertahankan, dan tidak ada NaN baru yang muncul akibat penggabungan. Tabel ketiga di output memperlihatkan hasilnya: kolom cabang hilang karena hanya dimiliki maret.

Nilai joinKolom yang dipertahankanMuncul NaN?
"outer" (default)Gabungan semua kolom dari semua tabelYa, untuk kolom yang tidak ada
"inner"Irisan kolom yang dimiliki semua tabelTidak

Kedua nilai join ini berlaku untuk penumpukan baris (axis=0) maupun penyandingan kolom (axis=1) yang dibahas pada Chapter ketiga Section ini. Sebelum sampai ke sana, Chapter berikutnya memperdalam penumpukan baris: bagaimana pandas menyelaraskan kolom yang namanya sama tetapi urutannya berbeda antar tabel, serta pilihan praktis ketika struktur kolom antar sumber memang tidak seragam. Panduan lengkap kedua operasi penggabungan ini tersedia pada halaman merging di dokumentasi resmi.