Sz
Sıfır Gecikme
veri bilimi · türkçe
Hakkımda🗺️ Haritam
Tümü
İnteraktif📖Rehber🛠Araç📊Vaka💼Kariyer🐍PY Playground🗄️SQL Playground🔍Regex📚Öğren🚀Proje
Ana sayfarehber

Veri temizleme: kirli veriden temiz veriye

2026 · pandas · 20 dakika okuma

Veri bilimciler zamanlarının %80'ini veri temizlemekle geçirir. Geriye kalan %20'de model kurar, analiz yapar. Bu oranı ilk duyduğumda inanamamıştım. 15 yıl sonra söyleyebilirim ki bu rakam düşük bile.

Temiz veri olmadan en iyi model bile işe yaramaz. Bu rehberde gerçek hayatta karşılaşacağın her türlü kirli veri sorununu ve pandas ile çözümünü ele alacağız.

1. Veriyi tanı — önce bak

Temizlemeden önce ne ile karşı karşıya olduğunu anlamalısın. Her proje şu üç komutla başlar:

import pandas as pd
import numpy as np

df = pd.read_csv('veri.csv')

# Temel bilgiler
print(df.shape)          # (satır, sütun)
print(df.dtypes)         # her sütunun tipi
print(df.isnull().sum()) # eksik değer sayısı

# İstatistiksel özet
print(df.describe())

# İlk 5 satır
print(df.head())

# Benzersiz değer sayıları
print(df.nunique())

# Eksik değer yüzdesi
eksik_yuzde = (df.isnull().sum() / len(df)) * 100
print(eksik_yuzde[eksik_yuzde > 0].sort_values(ascending=False))

2. Eksik değerler

Eksik değer her veri setinin baş belası. Ama hepsine aynı çözümü uygulamak hata. Önce neden eksik olduğunu anla.

# Eksik değerlerin dağılımı
print(df.isnull().sum())
print(df.isnull().mean() * 100)  # yüzde olarak

# ── Strateji 1: Sil ──────────────────────────────────
# %50'den fazla eksik olan sütunları sil
esik = 0.5
df = df.loc[:, df.isnull().mean() < esik]

# Herhangi bir sütunda eksik olan satırları sil
df = df.dropna()

# Belirli sütunlarda eksik olan satırları sil
df = df.dropna(subset=['yas', 'maas'])

# ── Strateji 2: Doldur ───────────────────────────────
# Sayısal: ortalama veya medyan ile doldur
df['yas'].fillna(df['yas'].median(), inplace=True)
df['maas'].fillna(df['maas'].mean(), inplace=True)

# Kategorik: mod (en sık değer) ile doldur
df['sehir'].fillna(df['sehir'].mode()[0], inplace=True)

# İleri doldurma (zaman serisi için)
df['satis'].fillna(method='ffill', inplace=True)

# Geri doldurma
df['satis'].fillna(method='bfill', inplace=True)

# ── Strateji 3: Tahmin et ────────────────────────────
from sklearn.impute import SimpleImputer, KNNImputer

# Ortalama ile doldur
imputer = SimpleImputer(strategy='median')
df[['yas', 'maas']] = imputer.fit_transform(df[['yas', 'maas']])

# KNN ile doldur (daha akıllı)
knn_imputer = KNNImputer(n_neighbors=5)
df[sayisal_sutunlar] = knn_imputer.fit_transform(df[sayisal_sutunlar])

Altın kural: Eksik değeri silmeden önce neden eksik olduğunu anla. Rastgele eksikse ortalama ile doldur. Sistematik eksikse (örn. kadınların geliri eksik) bu bir bilgi taşıyor, dikkatli ol.

3. Tekrar eden satırlar

Veri birleştirme, sistem hataları veya manuel giriş hatalarından kaynaklanır. Tespit etmek ve silmek genellikle kolaydır.

# Kaç tane tekrar var?
print(f"Toplam satır: {len(df)}")
print(f"Tekrar eden: {df.duplicated().sum()}")
print(f"Benzersiz: {df.duplicated().sum()} tekrar sonrası {len(df) - df.duplicated().sum()}")

# Tekrar eden satırları gör
print(df[df.duplicated(keep=False)])

# Tüm sütunlarda aynı olan satırları sil
df = df.drop_duplicates()

# Belirli sütunlara göre tekrar kontrol
df = df.drop_duplicates(subset=['musteri_id', 'siparis_tarihi'])

# Hangi tekrarı tut?
df = df.drop_duplicates(subset=['musteri_id'], keep='last')  # son kaydı tut
df = df.drop_duplicates(subset=['musteri_id'], keep='first') # ilk kaydı tut

4. Veri tipi sorunları

CSV'den okunan veri çoğu zaman yanlış tipte gelir. Tarihler string, sayılar object olabilir. Bu hem performansı hem analizin doğruluğunu etkiler.

# Tipleri kontrol et
print(df.dtypes)

# ── String → Sayı ────────────────────────────────────
# "1.234,56" → 1234.56 formatı
df['maas'] = df['maas'].str.replace('.', '').str.replace(',', '.').astype(float)

# Hatalı değerleri NaN'a çevir
df['yas'] = pd.to_numeric(df['yas'], errors='coerce')

# ── String → Tarih ───────────────────────────────────
df['tarih'] = pd.to_datetime(df['tarih'])
df['tarih'] = pd.to_datetime(df['tarih'], format='%d/%m/%Y')

# Tarihten özellik çıkar
df['yil'] = df['tarih'].dt.year
df['ay'] = df['tarih'].dt.month
df['gun'] = df['tarih'].dt.day
df['hafta_gunu'] = df['tarih'].dt.dayofweek  # 0=Pazartesi

# ── Kategorik tip ────────────────────────────────────
# Bellek tasarrufu ve hız için
df['sehir'] = df['sehir'].astype('category')
df['cinsiyet'] = df['cinsiyet'].astype('category')

# Bellek kullanımı karşılaştırması
print(df.memory_usage(deep=True))

5. String temizleme

Metin verisinde tutarsızlık çok yaygın. Boşluklar, büyük/küçük harf farkı, özel karakterler...

# Boşlukları temizle
df['isim'] = df['isim'].str.strip()

# Büyük/küçük harf standardize et
df['sehir'] = df['sehir'].str.lower()
df['isim'] = df['isim'].str.title()  # Her kelimenin baş harfi büyük

# Özel karakterleri kaldır
import re
df['telefon'] = df['telefon'].str.replace(r'[^0-9]', '', regex=True)

# Boş string → NaN
df['not'] = df['not'].replace('', np.nan)
df['not'] = df['not'].replace(['N/A', 'NA', 'null', 'NULL', '-'], np.nan)

# Tutarsız değerleri standardize et
sehir_map = {
    'istanbul': 'İstanbul',
    'İSTANBUL': 'İstanbul',
    'istanbul ': 'İstanbul',
    'izmir': 'İzmir',
    'İZMİR': 'İzmir',
}
df['sehir'] = df['sehir'].str.strip().map(sehir_map).fillna(df['sehir'])

6. Aykırı değerler

Aykırı değer her zaman hata değildir. Bazen gerçek, bazen veri girişi hatası, bazen dolandırıcılık sinyali. Silmeden önce anla.

# ── IQR Yöntemi ─────────────────────────────────────
Q1 = df['maas'].quantile(0.25)
Q3 = df['maas'].quantile(0.75)
IQR = Q3 - Q1

alt_sinir = Q1 - 1.5 * IQR
ust_sinir = Q3 + 1.5 * IQR

# Aykırı değerleri gör
aykiri = df[(df['maas'] < alt_sinir) | (df['maas'] > ust_sinir)]
print(f"Aykırı değer sayısı: {len(aykiri)}")

# Seçenek 1: Sil
df = df[(df['maas'] >= alt_sinir) & (df['maas'] <= ust_sinir)]

# Seçenek 2: Sınırla (winsorize)
df['maas'] = df['maas'].clip(lower=alt_sinir, upper=ust_sinir)

# Seçenek 3: NaN yap, sonra doldur
df.loc[df['maas'] > ust_sinir, 'maas'] = np.nan
df['maas'].fillna(df['maas'].median(), inplace=True)

# ── Z-Score Yöntemi ──────────────────────────────────
from scipy import stats
z_scores = np.abs(stats.zscore(df['maas']))
df = df[z_scores < 3]  # 3 standart sapmadan uzak olanları sil

7. Tam temizleme pipeline'ı

Tüm adımları tek bir fonksiyona toplamak yeniden kullanılabilirlik sağlar.

def temizle(df):
    """Standart veri temizleme pipeline'ı."""
    df = df.copy()
    
    # 1. Sütun adlarını standardize et
    df.columns = (df.columns
                  .str.strip()
                  .str.lower()
                  .str.replace(' ', '_')
                  .str.replace('ı', 'i')
                  .str.replace('ş', 's')
                  .str.replace('ğ', 'g')
                  .str.replace('ü', 'u')
                  .str.replace('ö', 'o')
                  .str.replace('ç', 'c'))
    
    # 2. Tekrar eden satırları sil
    df = df.drop_duplicates()
    
    # 3. Tipleri düzelt
    for col in df.select_dtypes('object').columns:
        # Sayıya çevrilebiliyorsa çevir
        converted = pd.to_numeric(df[col], errors='coerce')
        if converted.notna().sum() > len(df) * 0.8:
            df[col] = converted
    
    # 4. String sütunları temizle
    for col in df.select_dtypes('object').columns:
        df[col] = df[col].str.strip()
        df[col] = df[col].replace(['', 'N/A', 'NA', 'null', '-'], np.nan)
    
    # 5. %50+ eksik sütunları sil
    df = df.loc[:, df.isnull().mean() < 0.5]
    
    # 6. Sayısal eksikleri medyan ile doldur
    for col in df.select_dtypes('number').columns:
        df[col].fillna(df[col].median(), inplace=True)
    
    # 7. Kategorik eksikleri mod ile doldur
    for col in df.select_dtypes('object').columns:
        if df[col].notna().any():
            df[col].fillna(df[col].mode()[0], inplace=True)
    
    return df

# Kullan
df_temiz = temizle(df_ham)
print(f"Ham: {df_ham.shape} → Temiz: {df_temiz.shape}")

Altın kurallar

Sıradaki rehberde ETL ve data transformation: ham veriyi analiz için hazır hale getirmenin sistematik yolu.

Bunları da beğenebilirsin

rehber

Pandas'ta en çok yanlış bilinen 7 şey

15 dakika

rehber

Feature engineering: modelden önce gelen sanat

15 dakika

rehber

SQL temelleri: veri analistinin en önemli becerisi

20 dakika

Faydalı bulduysan paylaş

X'te paylaşLinkedIn'de paylaş

💬 Yorumlar