Ana içeriğe geç

Orta13 dk

Seçme, filtreleme, indeksleme

Önkoşul:Veri okuma ve tip sorunları

Kanca

300 satırlık bir sipariş tablon var. “Sadece Elektronik kategorisinde ve 200 TL üstü olan siparişleri göster” demek istiyorsun. Excel’de bunu filtre menüsüyle tıklardın — pandas’ta bunu tek satır kodla, ama doğru araçla yapman gerekiyor: .loc, .iloc, yoksa doğrudan köşeli parantez mi?

Sezgi

pandas’ta veriye erişmenin iki temel yolu var: .iloc, POZİSYONA göre erişir (Python listesi gibi, 0’dan başlar) — “3. satırı ver” dersin. .loc, ETİKETE göre erişir — “S2047 numaralı satırı ver” dersin, satırın kaçıncı sırada olduğu önemli değildir.

Filtreleme ise üçüncü bir mantıkla çalışır: bir koşul yazdığında (siparisler["tutar"] > 200), pandas önce True/False değerlerinden oluşan bir Series üretir, sonra bu Series’i “hangi satırları göstereyim” filtresi olarak kullanır. Bu, 2. derste NumPy’da gördüğümüz boolean indekslemenin ta kendisi.

Mekanizma

Önce .iloc ve .loc farkını görelim:

.iloc vs .loc

# .iloc: POZİSYONA göre (0'dan başlar, Python listesi gibi).
# .loc: ETİKETE göre (bizim indeksimiz sipariş numarası olduğu için).
print("İlk satır, .iloc[0] ile:")
print(siparisler.iloc[0])

print("\n'S2000' numaralı sipariş, .loc['S2000'] ile:")
print(siparisler.loc["S2000"])

print("\n.iloc ile ilk 3 satır, sadece tutar ve kategori sütunları:")
print(siparisler.iloc[0:3][["kategori", "tutar"]])
İlk satır, .iloc[0] ile:
musteri_id          1008
kategori      Ev & Yaşam
tutar             188.61
bolge                Ege
iade_mi            False
Name: S2000, dtype: object

'S2000' numaralı sipariş, .loc['S2000'] ile:
musteri_id          1008
kategori      Ev & Yaşam
tutar             188.61
bolge                Ege
iade_mi            False
Name: S2000, dtype: object

.iloc ile ilk 3 satır, sadece tutar ve kategori sütunları:
         kategori   tutar
S2000  Ev & Yaşam  188.61
S2001       Kitap   19.54
S2002  Elektronik   80.10

İkisi de aynı satırı getirdi çünkü ilk satırın konumu (0) ile etiketi (S2000) burada çakıştı — ama farklı bir satırda ikisi tamamen farklı sonuç verirdi. Şimdi boolean filtrelemeyle ilerleyelim:

Boolean filtreleme

# Koşula uyan satırları filtrelemek: köşeli parantez içine bir boolean Series koy.
pahali_siparisler = siparisler[siparisler["tutar"] > 200]
print(f"\n200 TL üstü sipariş sayısı: {len(pahali_siparisler)} / {len(siparisler)}")

# Birden fazla koşul: & (ve), | (veya) — HER koşulu parantez içine almak zorunludur.
elektronik_ve_pahali = siparisler[(siparisler["kategori"] == "Elektronik") & (siparisler["tutar"] > 200)]
print(f"Elektronik VE 200 TL üstü: {len(elektronik_ve_pahali)}")

marmara_veya_ege = siparisler[(siparisler["bolge"] == "Marmara") | (siparisler["bolge"] == "Ege")]
print(f"Marmara VEYA Ege: {len(marmara_veya_ege)}")

200 TL üstü sipariş sayısı: 65 / 300
Elektronik VE 200 TL üstü: 21
Marmara VEYA Ege: 163

& (ve) ve | (veya) ile koşulları birleştirdik — dikkat: her koşul kendi parantezi içinde olmak zorunda, yoksa Python operatör önceliği yüzünden hata alırsın. Çoğu kişi siparisler["tutar"] > 200 & siparisler["kategori"] == "Elektronik" gibi parantezsiz yazar ve garip bir hatayla karşılaşır. Değil, çünkü Python’da & operatörü > ve ==’den daha yüksek önceliklidir — parantez olmadan ifade tamamen farklı (ve genelde hatalı) bir şekilde gruplanır.

Matematik

Filtreleme mantığı
siparisler[kos¸ul]={satıri:kos¸uli=True}\text{siparisler}[\text{koşul}] = \{ \text{satır}_i : \text{koşul}_i = \text{True} \}
AraçNe zaman kullanılır
.iloc[i]Satırın konumunu (kaçıncı sırada olduğunu) biliyorsan
.loc[etiket]Satırın etiketini (indeks değerini) biliyorsan
df[koşul]Bir koşula uyan TÜM satırları filtrelemek istiyorsan
.loc[koşul, sütunlar]Hem satır filtresi hem sütun seçimini TEK satırda birleştirmek istiyorsan

& ve | operatörleri Python’un normal and/or anahtar kelimelerinden farklıdır — and/or tek bir True/False değeri bekler, ama pandas’ta bir Series’in tamamı için “ve/veya” işlemi yapmak istediğimizde &/| (eleman bazlı operatörler) kullanılır.

Kod

.loc’un asıl gücü, satır filtresi ve sütun seçimini birleştirebilmesi:

Satır filtresi + sütun seçimi birlikte

# .loc, satır filtresi VE sütun seçimini TEK satırda birleştirir.
iade_edilenler = siparisler.loc[siparisler["iade_mi"], ["kategori", "tutar", "bolge"]]
print(f"\nİade edilen sipariş sayısı: {len(iade_edilenler)}")
print(iade_edilenler.head())

İade edilen sipariş sayısı: 22
         kategori   tutar       bolge
S2004  Elektronik  182.59  İç Anadolu
S2018       Giyim  450.17     Akdeniz
S2035  Ev & Yaşam  248.80         Ege
S2083       Giyim   21.19     Marmara
S2088  Elektronik  196.98         Ege
Dört kategorinin ortalama sipariş tutarını gösteren yatay çubuk grafik.
Boolean filtrelemeyi her kategori için tekrarlayarak, gruplama olmadan da özet çıkarılabilir — ama 8. derste bunun çok daha kısa bir yolunu göreceğiz.

Nerede işe yarar

Seçme ve filtreleme, her pandas analizinin en sık kullanılan iki işlemidir:

  • Segment analizi. “Sadece İstanbul’daki, son 30 günde alışveriş yapan müşteriler” gibi çok koşullu filtreler.
  • Veri temizliği. Aykırı veya hatalı satırları (tutar < 0 gibi) bulup incelemek veya çıkarmak.
  • Raporlama. Belirli bir kritere uyan alt kümeyi çekip ayrı bir analiz veya rapor için kullanmak.

Bu 3 hatayı yaparsın:

  1. Çoklu koşullarda parantez unutmak — &/| önceliği yüzünden sessizce yanlış (veya hatalı) sonuç alırsın.
  2. and/or kullanmaya çalışmak — pandas Series’lerinde bunlar çalışmaz, &/| gerekir.
  3. .loc ve .iloc’u karıştırmak — özellikle indeksin sayısal ama sırasız olduğu durumlarda (filtreleme sonrası kalan indeksler gibi) bu ciddi hatalara yol açar.

Kendini test et

1. `.iloc` ile `.loc` arasındaki temel fark nedir?
  1. Aralarında fark yoktur
  2. .iloc pozisyona, .loc etikete göre erişir (doğru cevap)
  3. .loc sadece sayısal indekslerde çalışır
  4. .iloc sadece sütunlarda çalışır

Neden: .iloc her zaman 0'dan başlayan pozisyon kullanır (Python listesi gibi); .loc ise DataFrame'in gerçek indeks etiketlerini (sipariş numarası gibi) kullanır.

2. `siparisler[(siparisler["tutar"] > 200) & (siparisler["kategori"] == "Elektronik")]` ifadesinde parantezler neden zorunludur?
  1. Sadece okunabilirlik için, işlevsel bir zorunluluk yok
  2. Python'da & operatörü karşılaştırma operatörlerinden (>, ==) daha yüksek önceliklidir, parantezsiz ifade yanlış gruplanır (doğru cevap)
  3. pandas parantezsiz kodu çalıştırmaz
  4. Parantezler performansı artırır

Neden: Python'un operatör önceliği kuralları nedeniyle, parantez olmadan & işlemi karşılaştırmalardan ÖNCE uygulanmaya çalışılır ve bu hataya veya yanlış sonuca yol açar.

3. `.loc[koşul, ["kategori", "tutar"]]` ifadesi ne yapar?
  1. Sadece koşula uyan satırları döndürür, tüm sütunlarla
  2. Koşula uyan satırları VE sadece belirtilen sütunları birlikte döndürür (doğru cevap)
  3. Hata verir, bu sözdizimi geçersizdir
  4. Sadece sütunları döndürür, satır filtresini yok sayar

Neden: .loc[satır_filtresi, sütun_listesi] söz dizimi, satır filtrelemesi ile sütun seçimini tek bir işlemde birleştirir.

Özet

Özet

  • .iloc pozisyona (0'dan başlayan sıra), .loc etikete (indeks değeri) göre erişir.
  • Boolean filtreleme, bir koşuldan True/False Series üretip bunu satır filtresi olarak kullanır.
  • Çoklu koşullarda & (ve) ve | (veya) kullanılır — her koşul kendi parantezinde olmalıdır.
  • .loc[koşul, sütunlar], satır filtresini ve sütun seçimini tek satırda birleştirir.
  • and/or Python anahtar kelimeleri pandas Series'lerinde çalışmaz — &/| gerekir.
Sonraki adım: groupby ve pivot →