SettingWithCopyWarning, Pandas’ın bir DataFrame’e atama yaptığımızda yükseltebileceği bir uyarıdır. Bu, zincirleme atama yaptığımızda veya bir dilimden oluşturulmuş bir DataFrame kullandığımızda meydana gelebilir. Hepimizin daha önce karşılaştığı, Pandas kodlarında yaygın bir hata kaynağıdır. Uyarı, aslında düzgün çalışıyor gibi görünen kodlarda da belirebildiği için ayıklaması zor olabilir.
SettingWithCopyWarning’ı anlamak önemlidir çünkü veri manipülasyonunda olası sorunlara işaret eder. Bu uyarı, kodunuzun verileri amaçlandığı şekilde değiştirmiyor olabileceğini, bunun da istenmeyen sonuçlara ve izlenmesi zor, belirsiz hatalara yol açabileceğini gösterir.
Bu yazıda, pandas’taki SettingWithCopyWarning’ı ve bundan nasıl kaçınabileceğimizi inceleyeceğiz. Ayrıca Pandas’ın geleceğini ve copy_on_write seçeneğinin DataFrame’lerle çalışma şeklimizi nasıl değiştireceğini tartışacağız.
DataFrame Görünümleri (view) ve Kopyaları
Bir DataFrame’den bir dilim seçip onu bir değişkene atadığımızda, bir görünüm (view) ya da yeni bir DataFrame kopyası elde edebiliriz.
Görünümde, her iki DataFrame de aynı belleği paylaşır. Bu, her iki DataFrame’de de bulunan bir hücredeki bir değeri değiştirmenin ikisini birden değiştireceği anlamına gelir.
Kopyada ise yeni bellek ayrılır ve orijinaliyle aynı değerlere sahip bağımsız bir DataFrame oluşturulur. Bu durumda, DataFrame’ler birbirinden ayrıdır; birinde yapılan değişiklik diğerini etkilemez.
Pandas, mümkün olduğunda performansı iyileştirmek için kopya oluşturmayı kaçınmaya çalışır. Ancak önceden bir görünüm mü yoksa kopya mı elde edeceğimizi öngörmek imkânsızdır. SettingWithCopyWarning, bir DataFrame’e değer atadığımızda ve bunun başka bir DataFrame’in görünümü mü yoksa kopyası mı olduğunun belirsiz olduğu durumlarda yükseltilir.
Gerçek Verilerle SettingWithCopyWarning’ı Anlamak
SettingWithCopyWarning’ın nasıl oluştuğunu ve nasıl düzeltileceğini öğrenmek için Real Estate Data London 2024 adlı Kaggle veri setini kullanacağız.
Bu veri seti Londra’dan güncel emlak verileri içeriyor. Veri setinde bulunan sütunlara genel bir bakış:
addedOn: İlanın eklendiği tarih.
title: İlanın başlığı.
descriptionHtml: İlanın HTML açıklaması.
propertyType: Mülkün türü. Tür belirtilmemişse değer "Not Specified" olur.
sizeSqFeetMax: Maksimum büyüklük (fit kare cinsinden).
bedrooms: Yatak odası sayısı.
listingUpdatedReason: İlanın güncellenme nedeni (ör. yeni ilan, fiyat düşüşü).
price: İlanın fiyatı (sterlin).
Açık bir geçici değişkenle örnek
Diyelim ki türü belirtilmeyen tüm mülklerin ev olduğunu söylediler. Bu nedenle, propertyType değeri "Not Specified" olan tüm satırları "House" olarak güncellemek istiyoruz. Bunu yapmanın bir yolu, türü belirtilmemiş satırları geçici bir DataFrame değişkenine filtrelemek ve propertyType sütununu şu şekilde güncellemektir:
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"Altyapı:
Bu kodu çalıştırmak, pandas’ın SettingWithCopyWarning üretmesine neden olur:
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"Altyapı:
Bunun nedeni, pandas’ın no_property_type DataFrame’inin df’in bir görünümü mü yoksa kopyası mı olduğunu bilememesidir.
Bu bir sorundur çünkü aşağıdaki kodun davranışı, bunun bir görünüm mü yoksa kopya mı olduğuna bağlı olarak çok farklı olabilir.
Bu örnekte amacımız, orijinal DataFrame’i değiştirmektir. Bu yalnızca no_property_type bir görünümse gerçekleşir. Geri kalan kodumuz df’in değiştiği varsayımıyla çalışıyorsa, bunun garanti edilmesinin bir yolu olmadığından yanlış olabilir. Bu belirsiz davranış nedeniyle Pandas, bizi bu durumdan haberdar etmek için uyarıyı verir.
Kodumuz görünüm elde ettiğimiz için doğru çalışsa bile, sonraki çalıştırmalarda kopya elde edebiliriz ve kod istenen şekilde çalışmaz. Bu nedenle, bu uyarıyı görmezden gelmemek ve kodumuzun her zaman istediğimiz işi yaptığından emin olmak önemlidir.
Gizli bir geçici değişkenle örnek
Önceki örnekte, DataFrame’in bir kısmını açıkça no_property_type adlı bir değişkene atadığımız için geçici bir değişken kullanıldığı açıktır.
Ancak bazı durumlarda bu kadar açık değildir. SettingWithCopyWarning’ın en sık görüldüğü örnek, zincirleme indekslemedir. Son iki satırı tek satırla değiştirdiğimizi varsayalım:
İlk bakışta, geçici bir değişken oluşturuluyormuş gibi görünmez. Ancak bunu çalıştırmak da SettingWithCopyWarning ile sonuçlanır.
Bu kod şu şekilde yürütülür:
df[df["propertyType"] == "Not Specified"] değerlendirilir ve geçici olarak belleğe alınır.
Bu geçici bellek konumunun ["propertyType"] indeksi erişilir.
İndeks erişimleri tek tek değerlendirilir; dolayısıyla, zincirleme indeksleme aynı uyarıyla sonuçlanır çünkü ara sonuçların görünüm mü yoksa kopya mı olduğunu bilmiyoruz. Yukarıdaki kod temelde şununla aynıdır:
Bu örnek, [] kullanarak indeks erişimlerini zincirlediğimiz için sıklıkla zincirleme indeksleme olarak anılır. Önce [df["propertyType"] == "Not Specified"] sonra ["propertyType"]’e erişiriz.
SettingWithCopyWarning Nasıl Çözülür
Kodumuzu belirsizlik olmayacak şekilde yazmayı ve SettingWithCopyWarning’ın tetiklenmemesini öğrenelim. Uyarının, bir DataFrame’in başka bir DataFrame’in görünümü mü yoksa kopyası mı olduğuna ilişkin belirsizlikten kaynaklandığını öğrendik.
Bunu düzeltmenin yolu, oluşturduğumuz her DataFrame’in, eğer kopya istiyorsak kopya, görünüm istiyorsak görünüm olduğundan emin olmaktır.
Orijinal DataFrame’i güvenle loc ile değiştirmek
Orijinal DataFrame’i değiştirmek istediğimiz yukarıdaki örnekteki kodu düzeltelim. Geçici bir değişken kullanmaktan kaçınmak için loc indeksleyici özelliğini kullanın.
Bu kodla, loc indeksleyicisi üzerinden doğrudan orijinal df DataFrame’i üzerinde işlem yapıyoruz; bu yüzden ara değişkenlere gerek yok. Orijinal DataFrame’i doğrudan değiştirmek istediğimizde yapmamız gereken budur.
İlk bakışta bu hâlâ parametreler içerdiğinden zincirleme indeksleme gibi görünebilir; ama değildir. Her bir indekslemeyi tanımlayan şey köşeli parantezlerdir [].
Şunu unutmayın: loc kullanmak yalnızca değeri doğrudan atadığımızda güvenlidir; yukarıda yaptığımız gibi. Eğer bunun yerine geçici bir değişken kullanırsak, yine aynı soruna düşeriz. İşte sorunu çözmeyen iki örnek kod:
Geçici değişkenle loc kullanmak:
# Using loc plus temporary variable doesn’t fix the issue
no_property_type = df.loc[df["propertyType"]=="Not Specified"]
no_property_type["propertyType"]="House"Altyapı:
İndeksle birlikte loc kullanmak (zincirleme indeksleme ile aynı):
# Using loc plus indexing is the same as chained indexing
df.loc[df["propertyType"]=="Not Specified"]["propertyType"]="House"Altyapı:
Bu iki örnek, insanları genellikle yanıltır çünkü yaygın bir yanlış kanı, loc olduğu sürece orijinal veriyi değiştirdiğimizdir. Bu yanlıştır. Değerin orijinal DataFrame’e atandığından emin olmanın tek yolu, veriye erişirken ayrı bir indeksleme kullanmadan tek bir loc ile doğrudan atama yapmaktır.
Orijinal DataFrame’in kopyasıyla güvenle çalışmak için copy()
DataFrame’in bir kopyası üzerinde çalıştığımızdan emin olmak istediğimizde .copy() yöntemini kullanmalıyız.
Diyelim ki mülklerin fit kare başına fiyatını analiz etmemiz istendi. Orijinal veriyi değiştirmek istemiyoruz. Amacımız, analiz sonuçlarıyla yeni bir DataFrame oluşturup başka bir ekibe göndermek.
İlk adım bazı satırları filtrelemek ve veriyi temizlemektir. Özellikle şunları yapmamız gerekir:
sizeSqFeetMax tanımlı olmayan satırları kaldırın.
Fiyatın "POA" (price on application) olduğu satırları kaldırın.
Fiyatları sayısal değerlere dönüştürün (orijinal veri setinde fiyatlar şu biçimdedir: "£25,000,000")
Yukarıdaki adımları şu kodla yapabiliriz:
# 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"])Altyapı:
Fit kare başına fiyatı hesaplamak için, price sütununu sizeSqFeetMax sütununa bölen sonuçlardan oluşan yeni bir sütun oluştururuz:
Bu kodu çalıştırırsak, yine SettingWithCopyWarning alırız. Bu şaşırtıcı olmamalı çünkü açıkça properties_with_size_and_price adlı geçici bir DataFrame değişkeni oluşturup onu değiştirdik.
Orijinal DataFrame yerine verinin bir kopyasıyla çalışmak istediğimiz için, ilk satırda .copy() yöntemini kullanarak properties_with_size_and_price’ın bir görünüm değil, yeni bir DataFrame kopyası olduğundan emin olarak sorunu çözebiliriz:
Yeni sütun oluşturmak, değer atamayla aynı şekilde davranır. Kopya mı yoksa görünümle mi çalıştığımız belirsiz olduğunda pandas bir SettingWithCopyWarning yükseltir.
Verinin bir kopyasıyla çalışmak istiyorsak, .copy() yöntemini kullanarak bunu açıkça kopyalamalıyız. Sonrasında, yeni bir sütunu dilediğimiz şekilde atayabiliriz. Önceki örnekte pricePerSqFt sütununu oluştururken bunu yaptık.
Öte yandan, orijinal DataFrame’i değiştirmek istiyorsak iki durumu göz önünde bulundurmalıyız.
Yeni sütun tüm satırları kapsıyorsa, orijinal DataFrame’i doğrudan değiştirebiliriz. Alt küme satır seçimi yapmayacağımız için bu bir uyarıya neden olmaz. Örneğin, ev türünün eksik olduğu her satıra bir note sütunu ekleyebiliriz:
df["notes"]= df["propertyType"].apply(lambda house_type:"Missing house type"if house_type =="Not Specified"else"")Altyapı:
Yeni sütun yalnızca satırların bir alt kümesi için değer tanımlıyorsa, loc indeksleyicisini kullanabiliriz. Örneğin:
df.loc[df["propertyType"]=="Not Specified","notes"]="Missing house type"Altyapı:
Bu durumda, seçilmeyen satırlardaki değerler tanımsız kalacağından ilk yaklaşım tercih edilir; çünkü her satır için bir değer belirtmemize olanak tanır.
Pandas 3.0’da SettingWithCopyWarning Hatası
Şu anda, SettingWithCopyWarning yalnızca bir uyarıdır, hata değildir. Kodumuz yine çalışır ve Pandas sadece dikkatli olmamız için bizi bilgilendirir.
Resmi Pandas belgelerine göre, SettingWithCopyWarning 3.0 sürümünden itibaren artık kullanılmayacak ve varsayılan olarak gerçek bir hata ile değiştirilecek; bu da daha sıkı kod standartlarını zorunlu kılacak.
Kodumuzun gelecekteki pandas sürümleriyle uyumlu kalmasını sağlamak için, uyarı yerine hata yükseltecek şekilde şimdiden güncellememiz önerilir.
Bu, pandas’ı içe aktardıktan sonra şu seçeneği ayarlayarak yapılır:
import pandas as pd
pd.options.mode.copy_on_write =TrueAltyapı:
Bunu mevcut koda eklemek, kodumuzdaki her belirsiz atamayla ilgilendiğimizden emin olmamızı ve pandas 3.0’a güncellediğimizde kodun çalışmaya devam etmesini sağlar.
Sonuç
SettingWithCopyWarning, kodumuz bir değeri değiştirdiğimizde bunun bir görünüm mü yoksa kopya mı olduğu belirsizliğine düştüğünde ortaya çıkar. Bunu, ne istediğimizi her zaman açıkça belirterek çözebiliriz:
Kopyayla çalışmak istiyorsak, copy() yöntemini kullanarak açıkça kopyalamalıyız.
Orijinal DataFrame’i değiştirmek istiyorsak, loc indeksleyicisini kullanmalı ve ara değişkenler kullanmadan veriye erişirken değeri doğrudan atamalıyız.
Hata olmasa da bu uyarıyı görmezden gelmemeliyiz çünkü beklenmedik sonuçlara yol açabilir. Dahası, Pandas 3.0’dan itibaren varsayılan olarak hata olacak; bu yüzden mevcut kodumuzda pd.options.mode.copy_on_write = True ayarını etkinleştirerek kodumuzu geleceğe hazır hâle getirmeliyiz. Bu, kodun Pandas’ın gelecekteki sürümlerinde de çalışmasını sağlar.
Pandas hakkında daha fazla bilgi edinmek için şu kaynaklara göz atın:
.loc kullandığım hâlde neden SettingWithCopyWarning alıyorum?⌄
loc kullanmak her zaman güvenlidir ve df başka bir DataFrame’den oluşturulmadığı sürece uyarı tetiklemez veya beklenmedik davranışa yol açmaz. Örneğin, df veri setini okurken oluşturduğumuz DataFrame ise, bu güvenlidir. Ancak bir ara hesaplamanın sonucuysa, yalnızca copy() yöntemiyle kopyalanmışsa güvenlidir.
Ancak bu uyarıyı bastırmamak ya da görmezden gelmemek şiddetle tavsiye edilir; çünkü kodunuzun düşündüğünüz işi yapmıyor olabileceği anlamına gelir.
Yeni bir sütun eklerken SettingWithCopyWarning’i nasıl düzeltirim?⌄
Yeni bir sütun eklerken uyarıyı düzeltmek, değerlere atama yaparken olduğu gibidir. Verinin bir kopyası üzerinde çalışmayı amaçlıyorsanız DataFrame’i önce kopyaladığınızdan veya loc kullandığınızdan emin olun.
Bu kılavuzu takip ettim ama hâlâ SettingWithCopyWarning alıyorum. Nasıl düzeltebilirim?⌄
Pandas’ın en güncel sürümlerinde, bu eğitimdeki uygulamaları takip etmek herhangi bir uyarıyı tetiklememelidir.
Daha eski bir sürüm kullanıyorsanız, en son kararlı sürüme güncellemenizi tavsiye ederiz. Eski sürümlerde bu uyarıyla ilgili bilinen hatalar vardır ve kodda sorun olmadığı hâlde uyarı tetiklenebilir.
Pandas sürümü güncelse, altta yatan sorun muhtemelen bariz olmayan bir zincirleme indeksleme durumudur. DataFrame’in nasıl oluşturulduğunu dikkatle gözden geçirin.
CheapGPT’te full-stack mühendisi ve kurucuyum. Öğretmek her zaman tutkum oldu. Öğrencilik yıllarımdan itibaren diğer öğrencilere ders verme ve yardımcı olma fırsatlarını hevesle aradım. Bu tutku beni doktora yapmaya yönlendirdi; bu süreçte akademik çalışmalarımı desteklemek için araştırma görevlisi olarak da görev aldım. O yıllarda, geleneksel sınıf ortamında bağlar kurmaktan ve öğrenmeyi kolaylaştırmaktan büyük bir tatmin duydum. Ancak çevrim içi öğrenme platformlarının ortaya çıkmasıyla birlikte dijital eğitimin dönüştürücü potansiyelini fark ettim. Nitekim üniversitemizde bu tür bir platformun geliştirilmesinde aktif rol aldım. Geleneksel öğretim ilkelerini yenilikçi dijital yöntemlerle bütünleştirmeye derinden bağlıyım. Tutkum, yalnızca ilgi çekici ve bilgilendirici olmakla kalmayan, aynı zamanda bu dijital çağdaki öğrenenler için erişilebilir kurslar tasarlamaktır.
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
SettingWithCopyWarning, Pandas’ın bir DataFrame’e atama yaptığımızda yükseltebileceği bir uyarıdır. Bu, zincirleme atama yaptığımızda veya bir dilimden oluşturulmuş bir DataFrame kullandığımızda meydana gelebilir. Hepimizin daha önce karşılaştığı, Pandas kodlarında yaygın bir hata kaynağıdır. Uyarı, aslında düzgün çalışıyor gibi görünen kodlarda da belirebildiği için ayıklaması zor olabilir.SettingWithCopyWarning’ı anlamak önemlidir çünkü veri manipülasyonunda olası sorunlara işaret eder. Bu uyarı, kodunuzun verileri amaçlandığı şekilde değiştirmiyor olabileceğini, bunun da istenmeyen sonuçlara ve izlenmesi zor, belirsiz hatalara yol açabileceğini gösterir.Bu yazıda, pandas’taki
SettingWithCopyWarning’ı ve bundan nasıl kaçınabileceğimizi inceleyeceğiz. Ayrıca Pandas’ın geleceğini vecopy_on_writeseçeneğinin DataFrame’lerle çalışma şeklimizi nasıl değiştireceğini tartışacağız.DataFrame Görünümleri (view) ve Kopyaları
Bir DataFrame’den bir dilim seçip onu bir değişkene atadığımızda, bir görünüm (view) ya da yeni bir DataFrame kopyası elde edebiliriz.
Görünümde, her iki DataFrame de aynı belleği paylaşır. Bu, her iki DataFrame’de de bulunan bir hücredeki bir değeri değiştirmenin ikisini birden değiştireceği anlamına gelir.
Kopyada ise yeni bellek ayrılır ve orijinaliyle aynı değerlere sahip bağımsız bir DataFrame oluşturulur. Bu durumda, DataFrame’ler birbirinden ayrıdır; birinde yapılan değişiklik diğerini etkilemez.
Pandas, mümkün olduğunda performansı iyileştirmek için kopya oluşturmayı kaçınmaya çalışır. Ancak önceden bir görünüm mü yoksa kopya mı elde edeceğimizi öngörmek imkânsızdır.
SettingWithCopyWarning, bir DataFrame’e değer atadığımızda ve bunun başka bir DataFrame’in görünümü mü yoksa kopyası mı olduğunun belirsiz olduğu durumlarda yükseltilir.Gerçek Verilerle
SettingWithCopyWarning’ı AnlamakSettingWithCopyWarning’ın nasıl oluştuğunu ve nasıl düzeltileceğini öğrenmek için Real Estate Data London 2024 adlı Kaggle veri setini kullanacağız.Bu veri seti Londra’dan güncel emlak verileri içeriyor. Veri setinde bulunan sütunlara genel bir bakış:
addedOn: İlanın eklendiği tarih.title: İlanın başlığı.descriptionHtml: İlanın HTML açıklaması.propertyType: Mülkün türü. Tür belirtilmemişse değer"Not Specified"olur.sizeSqFeetMax: Maksimum büyüklük (fit kare cinsinden).bedrooms: Yatak odası sayısı.listingUpdatedReason: İlanın güncellenme nedeni (ör. yeni ilan, fiyat düşüşü).price: İlanın fiyatı (sterlin).Açık bir geçici değişkenle örnek
Diyelim ki türü belirtilmeyen tüm mülklerin ev olduğunu söylediler. Bu nedenle,
propertyTypedeğeri"Not Specified"olan tüm satırları"House"olarak güncellemek istiyoruz. Bunu yapmanın bir yolu, türü belirtilmemiş satırları geçici bir DataFrame değişkenine filtrelemek vepropertyTypesütununu şu şekilde güncellemektir:Bu kodu çalıştırmak, pandas’ın
SettingWithCopyWarningüretmesine neden olur:Bunun nedeni, pandas’ın
no_property_typeDataFrame’inindf’in bir görünümü mü yoksa kopyası mı olduğunu bilememesidir.Bu bir sorundur çünkü aşağıdaki kodun davranışı, bunun bir görünüm mü yoksa kopya mı olduğuna bağlı olarak çok farklı olabilir.
Bu örnekte amacımız, orijinal DataFrame’i değiştirmektir. Bu yalnızca
no_property_typebir görünümse gerçekleşir. Geri kalan kodumuzdf’in değiştiği varsayımıyla çalışıyorsa, bunun garanti edilmesinin bir yolu olmadığından yanlış olabilir. Bu belirsiz davranış nedeniyle Pandas, bizi bu durumdan haberdar etmek için uyarıyı verir.Kodumuz görünüm elde ettiğimiz için doğru çalışsa bile, sonraki çalıştırmalarda kopya elde edebiliriz ve kod istenen şekilde çalışmaz. Bu nedenle, bu uyarıyı görmezden gelmemek ve kodumuzun her zaman istediğimiz işi yaptığından emin olmak önemlidir.
Gizli bir geçici değişkenle örnek
Önceki örnekte, DataFrame’in bir kısmını açıkça
no_property_typeadlı bir değişkene atadığımız için geçici bir değişken kullanıldığı açıktır.Ancak bazı durumlarda bu kadar açık değildir.
SettingWithCopyWarning’ın en sık görüldüğü örnek, zincirleme indekslemedir. Son iki satırı tek satırla değiştirdiğimizi varsayalım:İlk bakışta, geçici bir değişken oluşturuluyormuş gibi görünmez. Ancak bunu çalıştırmak da
SettingWithCopyWarningile sonuçlanır.Bu kod şu şekilde yürütülür:
df[df["propertyType"] == "Not Specified"]değerlendirilir ve geçici olarak belleğe alınır.["propertyType"]indeksi erişilir.İndeks erişimleri tek tek değerlendirilir; dolayısıyla, zincirleme indeksleme aynı uyarıyla sonuçlanır çünkü ara sonuçların görünüm mü yoksa kopya mı olduğunu bilmiyoruz. Yukarıdaki kod temelde şununla aynıdır:
Bu örnek,
[]kullanarak indeks erişimlerini zincirlediğimiz için sıklıkla zincirleme indeksleme olarak anılır. Önce[df["propertyType"] == "Not Specified"]sonra["propertyType"]’e erişiriz.SettingWithCopyWarningNasıl ÇözülürKodumuzu belirsizlik olmayacak şekilde yazmayı ve
SettingWithCopyWarning’ın tetiklenmemesini öğrenelim. Uyarının, bir DataFrame’in başka bir DataFrame’in görünümü mü yoksa kopyası mı olduğuna ilişkin belirsizlikten kaynaklandığını öğrendik.Bunu düzeltmenin yolu, oluşturduğumuz her DataFrame’in, eğer kopya istiyorsak kopya, görünüm istiyorsak görünüm olduğundan emin olmaktır.
Orijinal DataFrame’i güvenle
locile değiştirmekOrijinal DataFrame’i değiştirmek istediğimiz yukarıdaki örnekteki kodu düzeltelim. Geçici bir değişken kullanmaktan kaçınmak için
locindeksleyici özelliğini kullanın.Bu kodla,
locindeksleyicisi üzerinden doğrudan orijinaldfDataFrame’i üzerinde işlem yapıyoruz; bu yüzden ara değişkenlere gerek yok. Orijinal DataFrame’i doğrudan değiştirmek istediğimizde yapmamız gereken budur.İlk bakışta bu hâlâ parametreler içerdiğinden zincirleme indeksleme gibi görünebilir; ama değildir. Her bir indekslemeyi tanımlayan şey köşeli parantezlerdir
[].Şunu unutmayın:
lockullanmak yalnızca değeri doğrudan atadığımızda güvenlidir; yukarıda yaptığımız gibi. Eğer bunun yerine geçici bir değişken kullanırsak, yine aynı soruna düşeriz. İşte sorunu çözmeyen iki örnek kod:lockullanmak:lockullanmak (zincirleme indeksleme ile aynı):Bu iki örnek, insanları genellikle yanıltır çünkü yaygın bir yanlış kanı,
locolduğu sürece orijinal veriyi değiştirdiğimizdir. Bu yanlıştır. Değerin orijinal DataFrame’e atandığından emin olmanın tek yolu, veriye erişirken ayrı bir indeksleme kullanmadan tek birlocile doğrudan atama yapmaktır.Orijinal DataFrame’in kopyasıyla güvenle çalışmak için
copy()DataFrame’in bir kopyası üzerinde çalıştığımızdan emin olmak istediğimizde
.copy()yöntemini kullanmalıyız.Diyelim ki mülklerin fit kare başına fiyatını analiz etmemiz istendi. Orijinal veriyi değiştirmek istemiyoruz. Amacımız, analiz sonuçlarıyla yeni bir DataFrame oluşturup başka bir ekibe göndermek.
İlk adım bazı satırları filtrelemek ve veriyi temizlemektir. Özellikle şunları yapmamız gerekir:
sizeSqFeetMaxtanımlı olmayan satırları kaldırın."POA"(price on application) olduğu satırları kaldırın."£25,000,000")Yukarıdaki adımları şu kodla yapabiliriz:
Fit kare başına fiyatı hesaplamak için,
pricesütununusizeSqFeetMaxsütununa bölen sonuçlardan oluşan yeni bir sütun oluştururuz:Bu kodu çalıştırırsak, yine
SettingWithCopyWarningalırız. Bu şaşırtıcı olmamalı çünkü açıkçaproperties_with_size_and_priceadlı geçici bir DataFrame değişkeni oluşturup onu değiştirdik.Orijinal DataFrame yerine verinin bir kopyasıyla çalışmak istediğimiz için, ilk satırda
.copy()yöntemini kullanarakproperties_with_size_and_price’ın bir görünüm değil, yeni bir DataFrame kopyası olduğundan emin olarak sorunu çözebiliriz:Yeni sütunları güvenle eklemek
Yeni sütun oluşturmak, değer atamayla aynı şekilde davranır. Kopya mı yoksa görünümle mi çalıştığımız belirsiz olduğunda pandas bir
SettingWithCopyWarningyükseltir.Verinin bir kopyasıyla çalışmak istiyorsak,
.copy()yöntemini kullanarak bunu açıkça kopyalamalıyız. Sonrasında, yeni bir sütunu dilediğimiz şekilde atayabiliriz. Önceki örnektepricePerSqFtsütununu oluştururken bunu yaptık.Öte yandan, orijinal DataFrame’i değiştirmek istiyorsak iki durumu göz önünde bulundurmalıyız.
notesütunu ekleyebiliriz:locindeksleyicisini kullanabiliriz. Örneğin:Bu durumda, seçilmeyen satırlardaki değerler tanımsız kalacağından ilk yaklaşım tercih edilir; çünkü her satır için bir değer belirtmemize olanak tanır.
Pandas 3.0’da
SettingWithCopyWarningHatasıŞu anda,
SettingWithCopyWarningyalnızca bir uyarıdır, hata değildir. Kodumuz yine çalışır ve Pandas sadece dikkatli olmamız için bizi bilgilendirir.Resmi Pandas belgelerine göre,
SettingWithCopyWarning3.0 sürümünden itibaren artık kullanılmayacak ve varsayılan olarak gerçek bir hata ile değiştirilecek; bu da daha sıkı kod standartlarını zorunlu kılacak.Kodumuzun gelecekteki pandas sürümleriyle uyumlu kalmasını sağlamak için, uyarı yerine hata yükseltecek şekilde şimdiden güncellememiz önerilir.
Bu, pandas’ı içe aktardıktan sonra şu seçeneği ayarlayarak yapılır:
Bunu mevcut koda eklemek, kodumuzdaki her belirsiz atamayla ilgilendiğimizden emin olmamızı ve pandas 3.0’a güncellediğimizde kodun çalışmaya devam etmesini sağlar.
Sonuç
SettingWithCopyWarning, kodumuz bir değeri değiştirdiğimizde bunun bir görünüm mü yoksa kopya mı olduğu belirsizliğine düştüğünde ortaya çıkar. Bunu, ne istediğimizi her zaman açıkça belirterek çözebiliriz:copy()yöntemini kullanarak açıkça kopyalamalıyız.locindeksleyicisini kullanmalı ve ara değişkenler kullanmadan veriye erişirken değeri doğrudan atamalıyız.Hata olmasa da bu uyarıyı görmezden gelmemeliyiz çünkü beklenmedik sonuçlara yol açabilir. Dahası, Pandas 3.0’dan itibaren varsayılan olarak hata olacak; bu yüzden mevcut kodumuzda
pd.options.mode.copy_on_write = Trueayarını etkinleştirerek kodumuzu geleceğe hazır hâle getirmeliyiz. Bu, kodun Pandas’ın gelecekteki sürümlerinde de çalışmasını sağlar.Pandas hakkında daha fazla bilgi edinmek için şu kaynaklara göz atın: