Eksik ve Bozuk Verilerle Çalışma: Veri Temizleme

Bir önceki derste, groupby ile veriyi gruplayıp özetlemeyi öğrenmiştiniz. Şimdi bir adım geri gidip şu soruyu soruyoruz: peki ya elimizdeki veri baştan eksik veya bozuksa? Bu derste, gerçek hayattaki verilerin neredeyse hiçbir zaman "tertemiz" gelmediğini, eksik değerleri nasıl tespit edip ele alacağınızı ve veri tiplerini nasıl düzelteceğinizi öğreneceksiniz. Bir sonraki derste ise temizlediğiniz bu veriyi görselleştirmeye başlayacaksınız; bu yüzden burada öğrendikleriniz, güzel ve doğru grafikler çizebilmenizin de temelini oluşturacak.

Bu derste ne yapacağız?

Bu dersin hedefi, bir Pandas DataFrame'inde eksik (boş) ve hatalı tipte verileri tespit etmeyi, bunları duruma göre doldurmayı ya da silmeyi ve sütunların veri tiplerini doğru hâle getirmeyi öğrenmektir. Dersin sonunda, dağınık bir veri setini analiz edilebilir, güvenilir bir hâle getirebileceksiniz.

Ön koşul olarak, önceki derslerde gördüğünüz DataFrame oluşturma, sütun seçme ve groupby ile temel gruplama işlemlerini bilmeniz yeterlidir. Bilgisayarınızda Python ve Pandas kütüphanesinin kurulu olduğu bir ortamda (örneğin Jupyter Notebook) çalışıyor olmanız beklenir. Arayüz görünümü kullandığınız sürüme göre küçük farklılıklar gösterebilir; endişelenmeyin, temel mantık aynıdır.

Kavram

Eksik veri, bir tablodaki bazı hücrelerin doldurulmamış olmasıdır. Bunu bir sınıf listesine benzetebilirsiniz: öğretmen yoklama alırken bazı öğrencilerin notunu unutmuş veya bazı satırlar boş kalmış olabilir. Bu boşluklarla karşılaştığınızda üç seçeneğiniz vardır: boşluğu makul bir değerle doldurmak (örneğin sınıfın not ortalamasını yazmak), o satırı tamamen listeden çıkarmak (öğrenci hiç sınava girmemişse), ya da boşluğu olduğu gibi bırakıp analiz sırasında dikkatli davranmak.

Pandas'ta eksik veriler genellikle NaN (Not a Number, yani "sayı değil") olarak gösterilir. Bu, hücrenin boş olduğunu belirten özel bir işarettir. Bozuk veri ise biraz farklıdır: örneğin bir "yaş" sütununda sayı yerine yanlışlıkla metin yazılmış olması ("otuz" yazıp 30 yazmamak gibi) ya da bir tarih sütununun metin olarak saklanması gibi durumlardır. Bu tür sorunlar, veri tipinin (dtype) yanlış olmasından kaynaklanır ve analiz yaparken hatalara yol açar. Bu yüzden veri temizleme, bir aşçının yemeğe başlamadan önce sebzeleri yıkayıp ayıklamasına benzer: temiz malzeme olmadan güvenilir bir sonuç elde edemezsiniz.

Adım adım uygulama

  1. Öncelikle eksik veri içeren küçük bir örnek DataFrame oluşturalım. Jupyter Notebook'ta yeni bir hücre açın ve aşağıdaki kodu yazın:
    import pandas as pd
    import numpy as np
    
    veri = {
        "isim": ["Ayşe", "Mehmet", "Elif", "Can"],
        "yas": [28, np.nan, 35, 41],
        "sehir": ["İstanbul", "Ankara", np.nan, "İzmir"]
    }
    
    df = pd.DataFrame(veri)
    print(df)
    Burada numpy kütüphanesini np takma adıyla içe aktarıyoruz çünkü eksik değeri temsil eden np.nan ifadesi bu kütüphaneden gelir. veri adlı sözlükte bazı hücrelere kasıtlı olarak np.nan yerleştirdik; bu, o hücrelerin eksik olduğunu simgeler.
  2. Çalıştır düğmesine (genellikle Run ya da klavyede Shift+Enter) basarak hücreyi çalıştırın. Çıktıda "yas" ve "sehir" sütunlarında NaN yazan hücreleri göreceksiniz.
  3. Eksik değerleri tespit etmek için isnull() fonksiyonunu kullanın:
    print(df.isnull())
    Bu kod, her hücre için eksikse True, doluysa False döndüren aynı boyutta bir tablo verir.
  4. Hangi sütunda kaç eksik değer olduğunu toplu görmek için:
    print(df.isnull().sum())
    Burada isnull() ile önce eksik/dolu tablosunu elde ediyoruz, ardından sum() ile her sütundaki True değerlerini (yani eksikleri) topluyoruz. Sonuç, hangi sütunda kaç eksik hücre olduğunu sayı olarak gösterir.
  5. Eksik değerleri sabit bir değerle doldurmak için fillna() kullanın. Örneğin "yas" sütunundaki boşlukları, sütunun ortalamasıyla doldurabilirsiniz:
    df["yas"] = df["yas"].fillna(df["yas"].mean())
    print(df)
    df["yas"].mean() ifadesi, "yas" sütunundaki mevcut sayıların ortalamasını hesaplar. fillna() ise eksik hücrelere bu ortalama değeri yerleştirir. Böylece eksik yaş bilgisi, mantıklı bir tahmini değerle tamamlanmış olur.
  6. Metin tipi bir sütundaki eksikleri de sabit bir yazıyla doldurabilirsiniz:
    df["sehir"] = df["sehir"].fillna("Bilinmiyor")
    print(df)
    Burada "sehir" sütunundaki boş hücre, "Bilinmiyor" metniyle dolduruldu. Bu yaklaşım, sayısal bir ortalama hesaplamanın anlamlı olmadığı metin sütunlarında sık kullanılır.
  7. Bazen doldurmak yerine, eksik değeri olan satırı tamamen silmek daha doğru olabilir. Bunun için dropna() kullanılır:
    df_temiz = df.dropna()
    print(df_temiz)
    Bu kod, herhangi bir sütununda hâlâ eksik değer kalan satırları tablodan çıkarıp yeni bir df_temiz tablosu oluşturur. Az sayıda eksik satır varsa ve silmek veri setini ciddi şekilde küçültmüyorsa bu yöntem tercih edilebilir.
  8. Şimdi veri tiplerini kontrol edelim. Bir sütunun hangi tipte saklandığını görmek için:
    print(df.dtypes)
    Bu komut her sütunun tipini listeler: sayılar için int64 veya float64, metinler için object gibi. Bir sayısal sütun yanlışlıkla metin (object) olarak görünüyorsa, bu bir uyarı işaretidir.
  9. Yanlış tipteki bir sütunu düzeltmek için astype() kullanılır. Örneğin "yas" sütununu tam sayıya çevirmek isterseniz:
    df["yas"] = df["yas"].astype(int)
    print(df.dtypes)
    astype(int), sütundaki ondalıklı sayıları tam sayıya dönüştürür. Bu işlem, eksik değerler doldurulmadan yapılırsa hata verebilir; bu yüzden önce doldurma, sonra tip düzeltme sırası izlenmelidir.
  10. Son olarak, temizlenmiş tabloyu tekrar yazdırarak sonucu kontrol edin:
    print(df)
    Artık tabloda NaN kalmadığını ve sütun tiplerinin doğru olduğunu görmelisiniz.

Sık karşılaşılan sorunlar

Hata / SorunOlası NedenÇözüm
TypeError: cannot convert float NaN to integerastype(int) çağrılırken sütunda hâlâ NaN değer olmasıÖnce fillna() ile tüm eksik değerleri doldurun, sonra astype() uygulayın.
fillna() sonrası değişikliğin kalıcı olmamasıSonucun yeni bir değişkene atanmamasıdf["sütun"] = df["sütun"].fillna(...) şeklinde sonucu tekrar sütuna atayın.
Ortalama alırken hata veya anlamsız sonuçmean() fonksiyonunun metin (object) tipteki bir sütuna uygulanmasıOrtalama sadece sayısal sütunlarda kullanılır; metin sütunlarında sabit bir değer veya "Bilinmiyor" gibi ifadeler tercih edin.
dropna() sonrası tablo neredeyse boş kalıyorÇok fazla satırda eksik değer olmasıSatır silmek yerine, uygun sütunlarda doldurma (fillna) yöntemini tercih edin.
Sütun tipi beklenmedik şekilde object görünüyorSütun içinde en az bir metin veya karışık veri bulunmasıdtypes ile kontrol edin, gerekirse hatalı hücreleri düzeltip astype() ile doğru tipe çevirin.

Mini görev

Kendi başınıza, en az beş satırlık ve içinde en az iki eksik değer bulunan bir DataFrame oluşturun (örneğin bir ürün stok listesi: ürün adı, fiyat, stok adedi). Ardından şu adımları uygulayın: eksik değerleri isnull().sum() ile tespit edin, sayısal bir sütundaki eksikleri o sütunun ortalamasıyla doldurun, metin sütunundaki eksikleri sabit bir ifadeyle doldurun ve son olarak tüm sütunların veri tiplerinin doğru olduğunu dtypes ile kontrol edin.

  • En az beş satırlık bir DataFrame oluşturuldu mu?
  • Tabloda en az iki eksik (NaN) değer var mı?
  • isnull().sum() ile eksikler doğru şekilde sayıldı mı?
  • Sayısal sütundaki eksik değer ortalama ile dolduruldu mu?
  • Metin sütunundaki eksik değer sabit bir ifadeyle dolduruldu mu?
  • dtypes çıktısı kontrol edilip gerekirse astype() ile düzeltme yapıldı mı?

Kendini sına

1. Pandas'ta eksik bir değeri temsil etmek için genellikle hangi ifade kullanılır?

2. Bir DataFrame'deki her sütunda kaç tane eksik değer olduğunu tek satırda görmek için hangi iki fonksiyon art arda kullanılır?

3. fillna() ile dropna() arasındaki temel fark nedir?

4. Bir sütunu ondalıklı sayıdan tam sayıya çevirmeden önce neden önce eksik değerleri doldurmak gerekir?

5. Bir sütunun veri tipini (dtype) öğrenmek için hangi komut kullanılır?

Cevaplar

1. NaN (Not a Number) ifadesi kullanılır; bu genellikle numpy kütüphanesinden np.nan olarak gelir.

2. Önce isnull() ile eksik/dolu tablosu oluşturulur, ardından sum() ile her sütundaki eksik sayısı toplanır: df.isnull().sum().

3. fillna() eksik değerleri belirli bir değerle doldurarak satırı korur; dropna() ise eksik değer içeren satırı (veya sütunu) tablodan tamamen çıkarır.

4. Çünkü astype(int) işlemi, sütunda hâlâ NaN varsa hata verir; tam sayıya dönüştürme yapılabilmesi için önce tüm eksiklerin doldurulmuş olması gerekir.

5. df.dtypes komutu kullanılır; bu komut her sütunun veri tipini listeler.

Bu dersi kayıt olmadan izleyebilirsin. İlerlemeni kaydetmek, sertifika almak ve puan tablosuna girmek için ücretsiz üye ol: Kayıt Ol