Pandas'ta Sütunlara Fonksiyon Uygulama: apply, map ve lambda
Beceri rehberi

Pandas'ta Sütunlara Fonksiyon Uygulama: apply, map ve lambda

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Pandas'ta bir sütuna ya da satıra kendi fonksiyonunuzu uygulamak için map, apply ve DataFrame.map kullanılır. Hangisinin ne zaman seçileceğini örneklerle öğrenirsiniz.

Bir bakışta

  1. Üç yöntem, fonksiyonun gördüğü şeyle ayrılır. map tek değer, apply bir satır ya da sütun, DataFrame.map her hücre için çalışır.
  2. Sözlükle map, kodları etikete çevirmenin pratik yoludur. Sözlükte olmayan değerler NaN döner; sonucu kontrol edin.
  3. Birden çok sütunlu hesapta axis=1 gerekir. Fonksiyon her satırı bir Series olarak alır.
  4. Önce vektörel yolu düşünün. Yerleşik işlemler Python fonksiyonu çağıran apply'dan genellikle daha hızlıdır.
  5. applymap yerine DataFrame.map kullanılır. pandas 2.1 sürümünden itibaren applymap kullanımdan kaldırıldı.

map, apply ve DataFrame.map: hangisi ne yapar

Pandas'ta bir sütundaki ya da tablodaki değerlere kendi fonksiyonunuzu uygulamak için üç araç öne çıkar ve en sık karıştırılan konu da budur. Series.map, bir sütundaki her değeri tek tek dönüştürür; fonksiyon, sözlük ya da başka bir Series alabilir. DataFrame.apply, fonksiyonu tablonun her sütununa ya da her satırına bütün olarak uygular. DataFrame.map ise tablodaki her hücreye, tek değer alıp tek değer döndüren bir fonksiyon uygular.

Farkın özü, fonksiyonun ne aldığıdır. map'te fonksiyon tek bir değer görür. DataFrame.apply'da fonksiyon bir Series görür: axis ile belirlenen yönde ya bir sütunun tamamını ya da bir satırın tamamını. Bu yüzden iki sütunu birlikte kullanan bir hesap (örneğin tutar ve kupon durumu) apply ile satır bazında yazılır; tek sütunu dönüştüren bir iş ise genellikle map ya da Series üzerindeki yöntemlerle çözülür.

Pandas'ın eski sürümlerinde DataFrame.applymap adlı bir yöntem vardı. pandas 2.1 sürümünden itibaren bu yöntem kullanımdan kaldırıldı ve yerine DataFrame.map geldi. Eski örneklerde applymap görürseniz, yeni kodda map kullanın.

Aracı seçerken tek soruyu sorun: fonksiyonum tek bir değeri mi, bir satırı mı, bir sütunu mu görecek?

Şekil 1

Aracı, fonksiyonun ne gördüğü belirler

Hangi yöntem?

Fonksiyonunuz neyi dönüştürüyor?
  1. Tek sütundaki her değeri, sözlük ya da fonksiyonlaSeries.mapEşleşmeyen sözlük anahtarı NaN olur.
  2. Satırdaki birkaç sütunu birlikte kullanıyorsunuzDataFrame.apply, axis=1Fonksiyon her satırı bir Series olarak alır.
  3. Her sütuna özet ya da dönüşüm uygulayacaksınızDataFrame.apply, axis=0Fonksiyon her sütunu bir Series olarak alır.
  4. Tablodaki her hücreye aynı işlemi yapacaksınızDataFrame.mapFonksiyon tek değer alıp tek değer döndürür.
Kaynak: pandas belgeleriMindset Institute

Series.map ile sütundaki değerleri eşlemek

Series.map'in en pratik kullanımı, kodlanmış değerleri okunur etiketlere çevirmektir. Bir sözlük verdiğinizde, sütundaki her değer sözlükte anahtar olarak aranır ve karşılığıyla değiştirilir:

import pandas as pd

df = pd.DataFrame({"kanal": ["web", "mobil", "magaza", "web"]}) etiket = {"web": "Web sitesi", "mobil": "Mobil uygulama"} df["kanal_adi"] = df["kanal"].map(etiket)

Pandas belgelerine göre sözlükte bulunmayan değerler NaN olur. Yukarıdaki örnekte "magaza" için sonuç NaN gelir. Bu bazen istenen davranıştır, bazen sessiz bir hatadır; eşleşmeyenleri kontrol etmek için sonucu isna ile sayın. Eşleşmeyenlere varsayılan bir değer vermek isterseniz, sonucu fillna ile doldurabilir ya da __missing__ tanımlayan bir sözlük alt sınıfı (örneğin defaultdict) verebilirsiniz.

Fonksiyonla kullanımda da aynı mantık işler:

df["kanal_buyuk"] = df["kanal"].map(lambda x: x.upper())

Eksik değerler konusunda na_action parametresine dikkat edin. na_action="ignore" verdiğinizde NaN değerler fonksiyona gönderilmeden olduğu gibi bırakılır; bu, str işlemi yapan fonksiyonların eksik değerde hata vermesini önler.

Sütunda yalnız metin temizliği yapacaksanız, map ve lambda yerine str erişimcisi (df["kanal"].str.upper()) daha kısa ve çoğu zaman daha hızlıdır. Saf Python'daki lambda, map ve filter fonksiyonları başka bir konudur; burada yalnız DataFrame ve Series bağlamı ele alınır.

DataFrame.apply ile satır ve sütun bazlı hesap

Birden çok sütuna bağlı bir değer üretmek istediğinizde apply, axis=1 ile kullanılır. Fonksiyon her satırı bir Series olarak alır ve sütunlara ad ile erişirsiniz:

siparis = pd.DataFrame({"tutar": [120, 80, 200], "kuponlu": [True, False, True]})

def segment(satir): if satir["tutar"] >= 100 and satir["kuponlu"]: return "buyuk" return "standart"

siparis["segment"] = siparis.apply(segment, axis=1)

Aynı işi lambda ile de yazabilirsiniz, ancak mantık birden fazla koşul içeriyorsa adlandırılmış fonksiyon okunabilirlik açısından daha iyidir. Fonksiyonun mutlaka bir değer döndürdüğünden emin olun; return yazmayı unutursanız sütun None dolar.

axis=0 (varsayılan) fonksiyonu her sütuna uygular. Her sütun için bir özet üretmek ya da sayısal sütunları normalleştirmek gibi işlerde kullanılır. Karışıklığı önlemek için eksen değerini açıkça yazın: pandas belgelerine göre 0 her sütunun, 1 her satırın fonksiyona verilmesi demektir.

Fonksiyon birden fazla değer döndürüyorsa result_type="expand" parametresi bunları ayrı sütunlara açar. Belgelere göre bu parametre yalnız axis=1 ile anlamlıdır. Fonksiyonunuza ek argüman geçirmek için args ya da anahtar sözcüklü argümanları doğrudan apply'a verebilirsiniz.

Pandas belgeleri, apply içinde gelen nesneyi değiştirmeyi desteklenmeyen bir kullanım olarak belirtir. Fonksiyon girdiyi değiştirmek yerine yeni bir değer döndürmelidir.

Önce vektörel yolu deneyin

apply ve map, her değer ya da satır için bir Python fonksiyonu çağırır. Veri büyüdükçe bu, pandas'ın yerleşik vektörel işlemlerine göre yavaş kalır. Pandas belgeleri de DataFrame.map için bunu açıkça söyler: eleman düzeyinde işlem için vektörel yol varsa onu tercih edin.

Yukarıdaki segment örneği vektörel olarak şöyle yazılabilir:

import numpy as np

buyuk = (siparis["tutar"] >= 100) & siparis["kuponlu"] siparis["segment"] = np.where(buyuk, "buyuk", "standart")

Koşullu atamalar için numpy'ın where ya da select işlevleri, metin işlemleri için str erişimcisi, tarih işlemleri için dt erişimcisi, eşleme için map ve sözlük, aralık sınıflandırması için cut ve qcut kullanılabilir. Bunlardan biri işi çözüyorsa apply'a gerek yoktur.

Bu, apply'ı kullanmamanız gerektiği anlamına gelmez. Mantık karmaşıksa, yerleşik bir işlemle ifade edilemiyorsa ya da satır sayısı küçükse apply doğru ve okunabilir bir çözümdür. Önemli olan, önce vektörel yolu düşünmek ve gerçekten yavaşlık yaşıyorsanız ölçüm yaparak karar vermektir.

Fonksiyon sayısal bir azaltma işlemiyse (toplam, ortalama gibi) ve NumPy fonksiyonu kullanıyorsanız, belgelerde raw=True parametresinin performansı belirgin biçimde artırdığı belirtilir; fonksiyon bu durumda satırı Series yerine ndarray olarak alır.

Sık yapılan hatalar

İlk hata eksen karışıklığıdır. Satır bazlı işlem için axis=1 gerekir; unutursanız fonksiyon sütunları alır ve sütun adı hatası ya da beklenmedik sonuç görürsünüz. İkinci hata, apply sonucunu yeni bir sütuna atamayı unutmaktır; apply yeni bir nesne döndürür, mevcut tabloyu değiştirmez.

Üçüncü hata, fonksiyondan değer döndürmemektir. Fonksiyonun tüm kollarında return olmalı; aksi halde bazı satırlar None olur. Dördüncü hata, eksik değerleri hesaba katmamaktır: NaN içeren bir sütuna string yöntemi uygulayan fonksiyon hata verir. map'te na_action="ignore" kullanmak ya da fonksiyonun içinde eksik değeri kontrol etmek çözümdür.

Beşinci hata, map ile sözlük kullanırken eşleşmeyen değerlerin NaN olduğunu görmemektir. Eşleşme sonrası NaN sayısını kontrol edin. Altıncı hata, eski adı kullanmaktır: yeni kodda applymap yerine DataFrame.map yazılmalıdır.

Son olarak, apply içinde döngü dönen veya dış dosyaya yazan ağır işler yapmayın. apply'ı saf bir dönüştürme aracı olarak tutun; yan etkiler hata ayıklamayı zorlaştırır.

Bu beceriyi Mindset programlarında nerede çalışırsınız

Veri bilimi programlarındaki Python ve Pandas modülleri, tablo verisi üzerinde dönüştürme ve temizleme becerisini uygulamalı olarak işler. Veri analistliği ve veri bilimi yolunda tablodan özellik üretmek, bu araçlar olmadan düşünülemez.

İlgili Mindset programı

Data Science Bootcamp

Sık sorulanlar

Sık sorulan sorular

apply ile map arasındaki fark nedir?

Series.map bir sütundaki her değeri tek tek dönüştürür ve fonksiyon, sözlük ya da Series alabilir. DataFrame.apply ise fonksiyonu tablonun her sütununa veya satırına bütün olarak uygular. Birden çok sütunu birlikte kullanan hesapta apply, tek sütunlu dönüşümde map uygundur.

axis=1 ne anlama gelir?

apply'da axis=1, fonksiyonun her satır için çağrılacağı ve satırı bir Series olarak alacağı anlamına gelir; sütunlara adlarıyla erişirsiniz. Varsayılan olan axis=0 ise fonksiyonu her sütuna uygular. Karışıklığı önlemek için eksen değerini açıkça yazmak iyi bir alışkanlıktır.

Lambda ile adlandırılmış fonksiyon arasında ne seçmeliyim?

Tek satırlık basit dönüşümde lambda kısa ve yeterlidir. Birden fazla koşul ya da adım içeren mantıkta adlandırılmış fonksiyon okunabilirliği artırır, test edilebilir ve yeniden kullanılabilir. Lambda'yı karmaşık hale getirmek, hata ayıklamayı zorlaştırır.

apply neden yavaş kalabilir?

Çünkü her satır ya da sütun için bir Python fonksiyonu çağrılır. Pandas ve NumPy'ın yerleşik vektörel işlemleri ise tüm sütunu tek seferde işler. Yavaşlık yaşıyorsanız önce işi np.where, str erişimcisi ya da aritmetik gibi yerleşik bir yolla ifade edebilir misiniz diye bakın.

applymap hâlâ kullanılabilir mi?

pandas belgelerine göre applymap, 2.1 sürümünde kullanımdan kaldırıldı ve DataFrame.map olarak yeniden adlandırıldı. Yeni kodda DataFrame.map kullanın; eski örneklerde applymap görürseniz aynı işi yaptığını bilin.

Pandas apply, map ve lambda ile Sütun Dönüştürme