Baris duplikat adalah entri yang tercatat lebih dari satu kali dalam sebuah tabel, dan pandas menyediakan duplicated untuk mendeteksinya serta drop_duplicates untuk membuangnya. Topik ini membahas deteksi duplikat utuh yang seluruh selnya identik, pembedaan duplikat utuh dengan duplikat pada kunci seperti pasangan waktu dan ruang, serta parameter keep dan subset pada keduanya. Dataset log sensor versi kotor membawa tiga baris duplikat deterministik sehingga setiap angka pada topik ini dapat direproduksi. Setelah topik ini dipraktikkan, baris ganda dapat dibuang tanpa menghilangkan data yang sebenarnya unik.
Mendeteksi duplikat utuh dengan duplicated#
Metode duplicated() menghasilkan mask boolean yang bernilai True pada baris yang isinya sama dengan baris sebelumnya, dan perilaku ini disebut keep="first" karena salinan yang dipertahankan adalah kemunculan pertamanya. Pada dataset kontrak, df.duplicated().sum() menghasilkan 3 karena tiga baris pengganda yang disisipkan pembangkit data terdeteksi semuanya. Apabila yang diinginkan adalah melihat seluruh anggota kelompok duplikat dan bukan hanya salinannya, parameter keep=False menandai keduanya sekaligus, dan hitungannya menjadi 6. Jalankan skrip berikut untuk melihat kedua cara itu beserta baris-baris yang terlibat.
import numpy as np
import pandas as pd
# Dataset kontrak versi kotor: log sensor tiga ruangan dengan NaN dan duplikat.
rng = np.random.default_rng(42)
n = 96
df = pd.DataFrame({
"waktu": pd.date_range("2026-01-05 07:00", periods=n, freq="15min"),
"ruang": rng.choice(["Lab A", "Lab B", "Ruang Arsip"], n, p=[0.4, 0.35, 0.25]),
"suhu_c": np.round(rng.normal(24, 1.5, n), 1),
"lembap_pct": np.round(rng.normal(60, 5, n), 1),
"status_sensor": rng.choice(["normal", "kalibrasi", "rusak"], n, p=[0.85, 0.10, 0.05]),
})
df.loc[rng.random(n) < 0.05, "suhu_c"] = np.nan
df.loc[rng.random(n) < 0.05, "lembap_pct"] = np.nan
df = pd.concat([df, df.sample(3, random_state=42)], ignore_index=True)
print("duplikat utuh (keep=\"first\") :", df.duplicated().sum())
print("baris dalam kelompok duplikat :", df.duplicated(keep=False).sum())
print(df[df.duplicated(keep=False)][["waktu", "ruang", "suhu_c", "lembap_pct"]])
print("baris awal :", len(df))
print("setelah drop_duplicates() :", len(df.drop_duplicates()))
print("setelah subset waktu+ruang :", len(df.drop_duplicates(subset=["waktu", "ruang"])))
print("subset waktu+ruang keep=\"last\" :", len(df.drop_duplicates(subset=["waktu", "ruang"], keep="last")))
print("duplikat pada kunci waktu+ruang :", df.duplicated(subset=["waktu", "ruang"]).sum())# menjalankan skrip penanganan duplikat
python3 duplikat.pyduplikat utuh (keep="first") : 3
baris dalam kelompok duplikat : 6
waktu ruang suhu_c lembap_pct
73 2026-01-06 01:15:00 Lab A 24.6 57.2
77 2026-01-06 02:15:00 Lab B 24.7 61.8
80 2026-01-06 03:00:00 Lab B 22.1 56.4
96 2026-01-06 03:00:00 Lab B 22.1 56.4
97 2026-01-06 02:15:00 Lab B 24.7 61.8
98 2026-01-06 01:15:00 Lab A 24.6 57.2
baris awal : 99
setelah drop_duplicates() : 96
setelah subset waktu+ruang : 96
subset waktu+ruang keep="last" : 96
duplikat pada kunci waktu+ruang : 3Tabel enam baris pada keluaran memperlihatkan tiga pasangan duplikat yang lengkap, yaitu indeks 73 dengan 98, 77 dengan 97, dan 80 dengan 96. Ketiganya identik pada setiap kolom, termasuk nilai NaN yang ikut tergandakan, karena baris penggandanya memang disalin utuh dari data aslinya. Mask duplicated inilah yang kemudian dipakai drop_duplicates di bagian berikutnya, sehingga deteksi dan pembuangan selalu berbagi definisi duplikat yang sama.
Membuang duplikat dengan drop_duplicates#
Metode drop_duplicates() membuang baris yang ditandai duplicated() dan mempertahankan baris pertama setiap kelompok sesuai default keep="first". Pada dataset ini jumlah baris turun dari 99 menjadi 96, persis sebesar tiga baris pengganda yang disisipkan pembangkit data, dan tidak ada satu baris unik pun yang ikut terbuang. Pilihan keep="last" menghasilkan jumlah yang sama yaitu 96 karena pasangannya identik di setiap kolom, sehingga mempertahankan kemunculan pertama atau terakhir tidak mengubah isi tabel, hanya mengubah indeks baris yang tersisa. Perbedaan itu menjadi penting apabila baris-barisnya tidak identik sepenuhnya, misalnya kolom catatan waktu pemasukan berbeda, karena keep="last" memilih versi yang lebih baru. Setiap pemanggilan tetap diverifikasi dengan len sebelum dan sesudahnya agar jumlah baris yang hilang diketahui, sama seperti kebiasaan pada topik Penghapusan dengan dropna.
Duplikat pada kunci waktu dan ruang#
Duplikat utuh bukan satu-satunya bentuk data ganda, dan definisi duplikat yang lebih ketat bertumpu pada kunci (key), yaitu kolom atau gabungan kolom yang seharusnya unik untuk setiap baris. Pada log sensor ini kunci yang wajar adalah pasangan waktu dan ruang karena satu ruangan seharusnya hanya mencatat satu pengukuran pada satu waktu. Ekspresi df.duplicated(subset=["waktu", "ruang"]) menerapkan definisi itu dan tetap menghasilkan 3 pada dataset ini, karena kolom waktu unik di sepanjang tabel sehingga kecocokan kunci hanya mungkin berasal dari penggandaan baris. Pembuangan dengan drop_duplicates(subset=["waktu", "ruang"], keep="last") pun turun ke 96 baris dengan hasil yang sama.
Kekuatan definisi kunci baru terasa apabila kecocokan tidak menyertakan seluruh kolom. Apabila sensor yang sama mencatat dua kali pada waktu yang sama dengan nilai pembacaan berbeda, duplicated() tanpa subset tidak menandainya sama sekali karena barisnya tidak identik, sedangkan duplikat kuncinya menandai keduanya sebagai pelanggaran keunikan. Karena itu kunci dipilih dari makna baris, bukan dari kebetulan kesamaan isi, dan hasil deteksinya diverifikasi sebelum pembuangan dijalankan.
Kesalahan umum#
Kesalahan yang lazim adalah menganggap drop_duplicates() tanpa parameter aman untuk semua kasus. Pemanggilan itu hanya menyaring baris yang identik di setiap kolom, sehingga baris ganda yang berbeda pada satu kolom pun lolos dan tetap terhitung dua kali pada agregasi berikutnya. Kesalahan lain adalah memilih kunci terlalu longgar atau terlalu ketat, misalnya hanya ruang yang akan membuang hampir seluruh baris karena setiap ruangan memuat banyak pengukuran, atau hanya waktu yang mengabaikan fakta bahwa tiga ruangan berbagi jadwal yang sama. Kedua kesalahan itu tidak memunculkan error, dan satu-satunya pengaman adalah menyebutkan definisi baris unik secara tertulis sebelum subset diisi, kemudian memverifikasi len hasilnya seperti yang dipraktikkan pada skrip topik ini.
Ringkasan#
duplicated()menandai salinan baris dengan defaultkeep="first", dankeep=Falsemenandai seluruh anggota kelompok duplikat untuk keperluan inspeksi.drop_duplicates()membuang baris bertanda, dan parametersubsetmengganti definisi duplikat dari kesamaan seluruh kolom menjadi keunikan kunci.- Duplikat utuh dan duplikat kunci dapat memberi hasil berbeda, sehingga kunci dipilih dari makna baris dan diverifikasi dengan
len. - Tiga baris ganda pada dataset kontrak terdeteksi utuh maupun melalui kunci
waktudanruangkarena kolomwaktuunik di sepanjang tabel.
Referensi#
- pandas.DataFrame.duplicated — pandas
— Dokumentasi metode
duplicateduntuk mendeteksi baris duplikat beserta parametersubsetdankeep. - pandas.DataFrame.drop_duplicates — pandas
— Dokumentasi metode
drop_duplicatesuntuk membuang baris duplikat dengan pilihan kunci dankeep.