Lewati ke konten utama

SettingWithCopyWarning di Pandas: Cara Memperbaiki Peringatan Ini

Pelajari cara memperbaiki SettingWithCopyWarning di Pandas: Ada nilai yang mencoba disetel pada salinan irisan dari sebuah DataFrame.
Diperbarui 28 Sep 2026  · 8 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

SettingWithCopyWarning adalah peringatan yang dapat muncul di Pandas saat kita melakukan penugasan (assignment) pada sebuah DataFrame. Ini bisa terjadi ketika kita menggunakan assignment berantai (chained assignments) atau saat kita menggunakan DataFrame yang dibuat dari sebuah slice. Ini adalah sumber bug yang umum dalam kode Pandas yang mungkin pernah kita alami. Peringatan ini sulit di-debug karena bisa muncul pada kode yang tampaknya sudah benar.

Memahami SettingWithCopyWarning penting karena ini menandakan potensi masalah dalam manipulasi data. Peringatan ini menunjukkan bahwa kode Anda mungkin tidak mengubah data seperti yang dimaksudkan, yang dapat menimbulkan konsekuensi tak terduga dan bug terselubung yang sulit dilacak.

Dalam artikel ini, kita akan membahas SettingWithCopyWarning di pandas dan cara menghindarinya. Kita juga akan membahas masa depan Pandas dan bagaimana opsi copy_on_write akan mengubah cara kita bekerja dengan DataFrame.

View dan Copy pada DataFrame

Saat kita memilih sebuah slice dari DataFrame dan menugaskannya ke sebuah variabel, kita bisa mendapatkan view atau salinan DataFrame yang baru.

Pada view, memori antara kedua DataFrame dibagi bersama. Artinya, mengubah nilai dari sebuah sel yang ada di kedua DataFrame akan mengubah keduanya.

Contoh view pada Pandas DataFrame

Pada copy, memori baru dialokasikan, dan dibuat DataFrame independen dengan nilai yang sama seperti yang asli. Dalam kasus ini, kedua DataFrame adalah entitas terpisah, sehingga mengubah nilai di salah satunya tidak memengaruhi yang lain.

Contoh salinan DataFrame

Pandas berusaha menghindari pembuatan salinan jika memungkinkan untuk mengoptimalkan kinerja. Namun, tidak mungkin diprediksi sebelumnya apakah kita akan mendapatkan view atau copy. SettingWithCopyWarning akan muncul setiap kali kita menetapkan nilai pada sebuah DataFrame yang tidak jelas apakah itu copy atau view dari DataFrame lain.

Memahami SettingWithCopyWarning dengan Data Nyata

Kita akan menggunakan dataset Kaggle Real Estate Data London 2024 untuk mempelajari bagaimana SettingWithCopyWarning terjadi dan cara memperbaikinya. 

Dataset ini berisi data properti terbaru dari London. Berikut gambaran umum kolom-kolom yang ada dalam dataset:

  • addedOn: Tanggal saat listing ditambahkan.
  • title: Judul listing.
  • descriptionHtml: Deskripsi listing dalam bentuk HTML.
  • propertyType: Jenis properti. Nilainya akan "Not Specified" jika jenisnya tidak ditentukan.
  • sizeSqFeetMax: Ukuran maksimum dalam satuan kaki persegi.
  • bedrooms: Jumlah kamar tidur.
  • listingUpdatedReason: Alasan pembaruan listing (misalnya, listing baru, penurunan harga).
  • price: Harga listing dalam poundsterling.

Contoh dengan variabel sementara eksplisit

Misalkan kita diberi tahu bahwa properti dengan jenis properti yang tidak ditentukan adalah rumah. Karena itu, kita ingin memperbarui semua baris dengan propertyType sama dengan "Not Specified" menjadi "House". Salah satu cara untuk melakukannya adalah memfilter baris dengan jenis properti yang tidak ditentukan ke dalam variabel DataFrame sementara dan memperbarui nilai kolom propertyType seperti ini:

import pandas as pd
dataset_name = "realestate_data_london_2024_nov.csv"
df = pd.read_csv(dataset_name)

# Obtain all rows with unspecified property type
no_property_type = df[df["propertyType"] == "Not Specified"]

# Update the property type to “House” on those rows
no_property_type["propertyType"] = "House"

Menjalankan kode ini akan membuat pandas menampilkan SettingWithCopyWarning:

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  no_property_type["propertyType"] = "House"

Alasannya adalah karena pandas tidak dapat mengetahui apakah DataFrame no_property_type merupakan view atau copy dari df. 

Saat kita menugaskan sebagian dataframe ke variabel, kita bisa mendapatkan view atau copy tetapi kita tidak tahu mana yang didapat

Ini menjadi masalah karena perilaku kode berikutnya bisa sangat berbeda tergantung apakah itu view atau copy. 

Dalam contoh ini, tujuan kita adalah mengubah DataFrame asli. Ini hanya akan terjadi jika no_property_type adalah view. Jika sisa kode kita mengasumsikan bahwa df telah diubah, asumsi itu bisa salah karena tidak ada cara untuk menjamin hal tersebut. Karena perilaku yang tidak pasti ini, Pandas memunculkan peringatan untuk memberi tahu kita.

Bahkan jika kode kita berjalan dengan benar karena kita mendapatkan view, pada eksekusi berikutnya kita bisa saja mendapatkan copy, dan kode tidak akan bekerja seperti yang diharapkan. Oleh karena itu, penting untuk tidak mengabaikan peringatan ini dan memastikan kode kita selalu melakukan apa yang kita inginkan.

Contoh dengan variabel sementara tersembunyi

Pada contoh sebelumnya, jelas bahwa sebuah variabel sementara digunakan karena kita secara eksplisit menugaskan sebagian DataFrame ke variabel bernama no_property_type.

Namun, dalam beberapa kasus, hal ini tidak begitu eksplisit. Contoh paling umum di mana SettingWithCopyWarning terjadi adalah pada chained indexing. Misalkan kita mengganti dua baris terakhir dengan satu baris:

df[df["propertyType"] == "Not Specified"]["propertyType"] = "House"

Sekilas, tampaknya tidak ada variabel sementara yang dibuat. Namun, mengeksekusinya juga menghasilkan SettingWithCopyWarning. 

Cara kode ini dieksekusi adalah:

  1. df[df["propertyType"] == "Not Specified"] dievaluasi dan disimpan sementara ke memori. 
  2. Indeks ["propertyType"] pada lokasi memori sementara tersebut diakses. 

Akses indeks dievaluasi satu per satu dan karena itu chained indexing menghasilkan peringatan yang sama karena kita tidak tahu apakah hasil antara adalah view atau copy

Akses indeks dievaluasi satu per satu, sehingga chained indexing menghasilkan peringatan yang sama karena kita tidak tahu apakah hasil antara tersebut merupakan view atau copy. Kode di atas pada dasarnya sama dengan melakukan:

tmp = df[df["propertyType"] == "Not Specified"]
tmp["propertyType"] = "House"

Contoh ini sering disebut chained indexing karena kita merangkai akses indeks menggunakan []. Pertama, kita mengakses [df["propertyType"] == "Not Specified"] lalu ["propertyType"].

Chained indexing

Cara Mengatasi SettingWithCopyWarning

Mari pelajari cara menulis kode agar tidak ada ambiguitas dan SettingWithCopyWarning tidak terpicu. Kita telah mempelajari bahwa peringatan ini muncul karena adanya ambiguitas apakah sebuah DataFrame adalah view atau copy dari DataFrame lain.

Cara memperbaikinya adalah memastikan setiap DataFrame yang kita buat benar-benar copy jika kita menginginkannya sebagai copy atau view jika kita menginginkannya sebagai view.

Mengubah DataFrame asli dengan aman menggunakan loc 

Mari perbaiki kode dari contoh di atas saat kita ingin mengubah DataFrame asli. Untuk menghindari penggunaan variabel sementara, gunakan properti indexer loc.

df.loc[df["propertyType"] == "Not Specified", "propertyType"] = "House"

Dengan kode ini, kita bertindak langsung pada DataFrame df asli melalui properti indexer loc, sehingga tidak diperlukan variabel perantara. Inilah yang perlu kita lakukan ketika kita ingin langsung memodifikasi DataFrame asli.

Sekilas ini mungkin terlihat seperti chained indexing karena masih ada parameter, tetapi sebenarnya bukan. Yang menentukan setiap indexing adalah tanda kurung siku [].

Perbedaan indeks ganda loc vs chained indexing

Perlu dicatat bahwa penggunaan loc hanya aman jika kita langsung menetapkan nilai, seperti yang kita lakukan di atas. Jika kita malah menggunakan variabel sementara, kita kembali pada masalah yang sama. Berikut dua contoh kode yang tidak memperbaiki masalah: 

  1. Menggunakan loc dengan variabel sementara:
# Menggunakan loc ditambah variabel sementara tidak memperbaiki masalah
no_property_type = df.loc[df["propertyType"] == "Not Specified"]
no_property_type["propertyType"] = "House"
  1. Menggunakan loc bersama dengan indexing (sama seperti chained indexing):
# Menggunakan loc lalu indexing sama saja dengan chained indexing
df.loc[df["propertyType"] == "Not Specified"]["propertyType"] = "House"

Kedua contoh ini sering membingungkan karena ada anggapan umum bahwa selama ada loc, kita sedang memodifikasi data asli. Ini tidak benar. Satu-satunya cara untuk memastikan bahwa nilai ditetapkan ke DataFrame asli adalah menetapkannya langsung menggunakan satu loc tanpa indexing terpisah.

Bekerja dengan aman pada salinan DataFrame asli menggunakan copy()

Ketika kita ingin memastikan bahwa kita beroperasi pada salinan DataFrame, kita harus menggunakan metode .copy().

Misalkan kita diminta menganalisis harga per kaki persegi dari properti. Kita tidak ingin mengubah data asli. Tujuannya adalah membuat DataFrame baru dengan hasil analisis untuk dikirim ke tim lain.

Langkah pertama adalah memfilter beberapa baris dan membersihkan data. Secara khusus, kita perlu:

  • Menghapus baris di mana sizeSqFeetMax tidak terdefinisi.
  • Menghapus baris di mana price adalah "POA" (price on application).
  • Mengonversi harga menjadi nilai numerik (di dataset asli, harga berupa string dengan format: "£25,000,000")

Kita dapat melakukan langkah-langkah di atas menggunakan kode berikut:

# 1. Filter out all properties without a size or a price
properties_with_size_and_price = df[df["sizeSqFeetMax"].notna() & (df["price"] != "POA")]

# 2. Remove the £ and , characters from the price columns
properties_with_size_and_price["price"] = properties_with_size_and_price["price"].str.replace("£", "", regex=False).str.replace(",", "", regex=False)

# 3. Convert the price column to numeric values
properties_with_size_and_price["price"] = pd.to_numeric(properties_with_size_and_price["price"])

Untuk menghitung harga per kaki persegi, kita membuat kolom baru dengan nilai hasil pembagian kolom price dengan kolom sizeSqFeetMax:

properties_with_size_and_price["pricePerSqFt"] = properties_with_size_and_price["price"] / properties_with_size_and_price["sizeSqFeetMax"]

Jika kita menjalankan kode ini, kita kembali mendapatkan SettingWithCopyWarning. Ini tidak mengejutkan karena kita secara eksplisit membuat dan memodifikasi variabel DataFrame sementara properties_with_size_and_price.

Karena kita ingin bekerja pada salinan data, bukan DataFrame asli, kita bisa memperbaiki masalah dengan memastikan bahwa properties_with_size_and_price adalah salinan DataFrame baru, bukan view, dengan menggunakan metode .copy() pada baris pertama:

properties_with_size_and_price = df[df["sizeSqFeetMax"].notna() & (df["price"] != "POA")].copy()

Menambahkan kolom baru dengan aman

Membuat kolom baru berperilaku sama seperti menetapkan nilai. Kapan pun ada ambiguitas apakah kita bekerja dengan copy atau view, pandas akan memunculkan SettingWithCopyWarning.

Jika kita ingin bekerja dengan salinan data, kita harus menyalinnya secara eksplisit menggunakan metode .copy(). Setelah itu, kita bebas menetapkan kolom baru dengan cara apa pun. Ini yang kita lakukan saat membuat kolom pricePerSqFt pada contoh sebelumnya.

Di sisi lain, jika kita ingin memodifikasi DataFrame asli ada dua kasus yang perlu dipertimbangkan. 

  1. Jika kolom baru mencakup setiap baris, kita dapat langsung memodifikasi DataFrame asli. Ini tidak akan menyebabkan peringatan karena kita tidak akan memilih subset baris. Misalnya, kita bisa menambahkan kolom note untuk setiap baris di mana jenis rumah tidak ada: 
df["notes"] = df["propertyType"].apply(lambda house_type: "Missing house type" if house_type == "Not Specified" else "")
  1. Jika kolom baru hanya mendefinisikan nilai untuk sebagian baris, maka kita dapat menggunakan properti indexer loc. Misalnya:
df.loc[df["propertyType"] == "Not Specified", "notes"] = "Missing house type"

Perhatikan bahwa dalam kasus ini, nilai pada kolom yang tidak dipilih akan tidak terdefinisi sehingga pendekatan pertama lebih disukai karena memungkinkan kita menentukan nilai untuk setiap baris.

Kesalahan SettingWithCopyWarning di Pandas 3.0

Saat ini, SettingWithCopyWarning hanyalah peringatan, bukan kesalahan. Kode kita tetap dieksekusi, dan Pandas hanya memberi tahu kita agar berhati-hati. 

Menurut dokumentasi resmi Pandas, SettingWithCopyWarning tidak akan digunakan lagi mulai versi 3.0 dan akan digantikan oleh kesalahan sesungguhnya secara default, menerapkan standar kode yang lebih ketat.

Informasi pembaruan Pandas 3.0

Agar kode kita tetap kompatibel dengan versi pandas mendatang, disarankan untuk segera memperbaruinya agar memunculkan error alih-alih peringatan.

Ini dilakukan dengan mengatur opsi berikut setelah mengimpor pandas:

import pandas as pd
pd.options.mode.copy_on_write = True

Menambahkan ini pada kode yang ada akan memastikan kita menangani setiap penugasan ambigu dalam kode dan memastikan kode tetap berfungsi saat kita memperbarui ke pandas 3.0.

Kesimpulan

SettingWithCopyWarning terjadi setiap kali kode kita menimbulkan ambiguitas apakah nilai yang kita ubah berasal dari view atau copy. Kita dapat memperbaikinya dengan selalu tegas mengenai apa yang kita inginkan:

  • Jika kita ingin bekerja dengan copy, kita harus menyalinnya secara eksplisit menggunakan metode copy().
  • Jika kita ingin memodifikasi DataFrame asli, kita harus menggunakan properti indexer loc dan menetapkan nilai secara langsung saat mengakses data tanpa menggunakan variabel perantara.

Meskipun bukan error, kita tidak boleh mengabaikan peringatan ini karena dapat menimbulkan hasil yang tidak terduga. Selain itu, mulai Pandas 3.0, ini akan menjadi error secara default, sehingga kita perlu menyiapkan kode untuk masa depan dengan mengaktifkan Copy-on-Write pada kode saat ini menggunakan pd.options.mode.copy_on_write = True. Ini akan memastikan kode tetap berfungsi untuk versi Pandas mendatang.

Untuk mempelajari lebih lanjut tentang Pandas, pertimbangkan sumber berikut:

FAQs

Mengapa saya mendapatkan SettingWithCopyWarning meskipun sudah menggunakan .loc?

Menggunakan loc selalu aman dan tidak akan memicu peringatan maupun menyebabkan perilaku tak terduga, dengan catatan df tidak dibuat dari DataFrame lain. Misalnya, jika df adalah DataFrame yang dibuat dari membaca dataset, maka itu aman. Namun, jika itu adalah hasil perhitungan perantara, maka hanya aman jika DataFrame tersebut disalin menggunakan metode copy().

Bagaimana cara menonaktifkan SettingWithCopyWarning?

Kita dapat menggunakan paket warnings dan menambahkan kode:

import warnings
warnings.simplefilter(action='ignore', category=pd.errors.SettingWithCopyWarning)

Namun, sangat tidak disarankan untuk menekan atau mengabaikan peringatan ini, karena ini berarti kode Anda mungkin tidak melakukan apa yang Anda kira.

Bagaimana cara mengabaikan SettingWithCopyWarning?

Kita dapat mengabaikan peringatan sementara menggunakan paket warnings dan membungkus kode kita dengan:

import warnings
with warnings.catch_warnings():
    warnings.simplefilter("ignore", category=pd.errors.SettingWithCopyWarning)
  # Our code goes here

Namun, sangat tidak disarankan untuk menekan atau mengabaikan peringatan ini, karena ini berarti kode Anda mungkin tidak melakukan apa yang Anda kira.

Bagaimana cara memperbaiki SettingWithCopyWarning saat menambahkan kolom baru?

Memperbaiki peringatan saat menambahkan kolom dilakukan dengan cara yang sama seperti saat menetapkan nilai. Pastikan untuk menyalin DataFrame terlebih dahulu jika Anda bermaksud bekerja pada salinan data atau gunakan loc.

Saya sudah mengikuti panduan ini, tetapi masih mendapatkan SettingWithCopyWarning. Bagaimana cara memperbaikinya?

Pada versi pandas terbaru, mengikuti praktik dari tutorial ini seharusnya tidak memicu peringatan apa pun.

Jika Anda menggunakan versi lama, kami menyarankan untuk memperbaruinya ke versi stabil terbaru. Versi lama diketahui memiliki bug terkait peringatan ini dan dapat memicunya meskipun tidak ada masalah pada kode.

Jika versi pandas sudah terbaru, kemungkinan masalah yang mendasari adalah kasus chained indexing yang tidak terlihat jelas. Tinjau dengan saksama bagaimana DataFrame dibuat.


François Aubry's photo
Author
François Aubry
LinkedIn
Insinyur full-stack & pendiri di CheapGPT. Mengajar selalu menjadi passion saya. Sejak masa awal sebagai mahasiswa, saya aktif mencari peluang untuk membimbing dan membantu mahasiswa lain. Passion ini mendorong saya menempuh studi PhD, di mana saya juga menjadi asisten pengajar untuk mendukung kegiatan akademik saya. Selama tahun-tahun itu, saya menemukan kepuasan besar dalam suasana kelas tradisional, membangun koneksi dan memfasilitasi proses belajar. Namun, dengan hadirnya platform pembelajaran daring, saya melihat potensi transformatif pendidikan digital. Bahkan, saya terlibat aktif dalam pengembangan salah satu platform tersebut di universitas kami. Saya sangat berkomitmen untuk mengintegrasikan prinsip-prinsip pengajaran tradisional dengan metodologi digital yang inovatif. Tujuan saya adalah menciptakan kursus yang tidak hanya menarik dan informatif, tetapi juga mudah diakses oleh para pembelajar di era digital ini.
Topik
Data Science
Python

Pelajari Pandas dengan kursus-kursus ini!

Kursus

Menggabungkan Data dengan pandas

4 jam
228K
Pelajari cara menggabungkan data dari beberapa tabel dengan menggabungkan data menggunakan pandas.
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

Lihat SelengkapnyaLihat Selengkapnya