Section ini berulang kali menggabungkan tabel yang berdiri berdampingan, tetapi belum menyentuh pola yang paling sering muncul di lapangan: dua versi dari tabel yang sama, masing-masing punya lubang di tempat berbeda. Hasil audit terbaru lebih akurat untuk sebagian baris, sementara catatan lama masih menjadi satu-satunya sumber untuk baris lainnya. Method combine_first() menjawab pola ini: nilai pemanggil dipakai bila tersedia, dan setiap nilai kosong ditambal dari tabel argumen. Chapter ini membahas arah penambalan pada combine_first(), kenaikan dtype akibat NaN, serta update() yang menimpa data langsung tanpa membuat tabel baru.

Arah Penambalan #

Kunci membaca df.combine_first(other) adalah urutan panggilannya: df adalah sumber utama dan other hanya menjadi cadangan. Pada contoh berikut, stok_baru.combine_first(stok_lama) memakai angka dari hasil audit terbaru, lalu mengisi seluruh NaN dari catatan lama. Kolom Kopi Gayo mengambil stok baru 130, sementara harga baris itu kosong di tabel baru sehingga ditambal 15_000 dari tabel lama. Nilai NaN di tabel lama yang tetap kosong di tabel baru tidak akan pernah terisi, karena tidak ada sumber ketiga.

python
import pandas as pd

stok_lama = pd.DataFrame(
    {
        "stok": [120, 85, None, 60],
        "harga": [15_000, None, 22_000, 18_000],
    },
    index=["Kopi Gayo", "Teh Melati", "Gula Aren", "Susu UHT"],
)
stok_baru = pd.DataFrame(
    {
        "stok": [130, 85, 75, None],
        "harga": [None, 16_500, 23_000, 19_000],
    },
    index=["Kopi Gayo", "Teh Melati", "Gula Aren", "Susu UHT"],
)
print(stok_lama)

# combine_first: nilai pemanggil dipakai, nilai kosong ditambal dari argumen
gabungan = stok_baru.combine_first(stok_lama)
print("\nhasil combine_first:")
print(gabungan)

# update(): timpa langsung dengan nilai non-NaN dari tabel lain
induk = pd.DataFrame(
    {"harga": [15_500, 17_000, 22_500, 18_500]},
    index=["Kopi Gayo", "Teh Melati", "Gula Aren", "Susu UHT"],
)
stok_lama.update(induk)
print("\nstok_lama setelah update harga:")
print(stok_lama["harga"])

Output yang Dihasilkan:

text
             stok    harga
Kopi Gayo   120.0  15000.0
Teh Melati   85.0      NaN
Gula Aren     NaN  22000.0
Susu UHT     60.0  18000.0

hasil combine_first:
             stok    harga
Kopi Gayo   130.0  15000.0
Teh Melati   85.0  16500.0
Gula Aren    75.0  23000.0
Susu UHT     60.0  19000.0

stok_lama setelah update harga:
Kopi Gayo     15500.0
Teh Melati    17000.0
Gula Aren     22500.0
Susu UHT      18500.0
Name: harga, dtype: float64

Mari kita telaah baris-baris kuncinya:

  1. Baris 4-16: dua DataFrame empat baris dengan index nama produk disiapkan; keduanya sengaja memiliki None di sel yang berbeda.
  2. Baris 21-23: stok_baru.combine_first(stok_lama) menghasilkan tabel penuh tanpa NaN; nilai pemanggil menang di setiap sel yang terisi.
  3. Baris 26-30: induk berisi harga resmi baru untuk semua produk, dan stok_lama.update(induk) menimpa kolom harga secara langsung tanpa penugasan kembali.

Dtype Naik Akibat NaN #

Perhatikan hasil combine_first(): kolom stok dan harga yang semula integer berubah menjadi float64. Penyebabnya adalah kehadiran NaN pada tabel sumber sebelum penambalan; NaN adalah float, sehingga pandas menaikkan seluruh kolom ke float64 demi menyimpannya. Setelah semua lubang tertambal tidak ada lagi NaN, tetapi dtype hasil tetap float karena tipe data diputuskan saat kolom dibentuk. Bila kolom hasil harus kembali ke integer, panggil .astype("int64") setelah memastikan tidak ada nilai kosong tersisa, atau gunakan nullable dtype Int64 dari section Advanced Pandas agar kehadiran NaN tidak memaksa kenaikan tipe.

update() untuk Penimpaan Langsung #

combine_first() mengembalikan DataFrame baru, sedangkan DataFrame.update() mengubah pemanggilnya di tempat. Aturan penggantian update() berbeda dari penambalan: setiap sel yang memiliki nilai non-NaN di tabel argumen menimpa sel pemanggil, dan sel yang NaN di argumen dibiarkan. Pada contoh, harga resmi induk menimpa seluruh kolom harga stok_lama, termasuk sel yang semula sudah terisi 15_000. Karena sifatnya menimpa, update() cocok untuk sinkronisasi terkendali dari tabel induk, bukan untuk penggabungan dua sumber yang sama bobotnya.

Method ini melengkapi keluarga penggabungan baris dan kolom pada section ini: concat menumpuk, merge mencocokkan kunci, dan combine_first() menambal lubang. Chapter berikutnya tetap di tema perbandingan data, tetapi dari sudut berbeda — menemukan sel yang berbeda antara dua versi tabel dengan compare().

Dokumentasi resmi yang relevan: pandas.DataFrame.combine_first untuk aturan penambalan dan penyelarasan index, pandas.DataFrame.update untuk parameter join dan overwrite, serta User Guide: Merge, join, concatenate and compare yang mengelompokkan keduanya.