SQL Sorgularının Pandas Karşılıkları

Murat Açıkgöz
Kodluyoruz
Published in
4 min readAug 24, 2020

Kendime not diye çıktığım yolda, ihtiyaç notlarımdan oluşan bir kesiti sizlerinde paylaşımına sunuyorum.

Bu içerikte, temel SQL sorgularının Python Pandas 🐼 kütüphanesinde derlenmiş karşılıklarını bulabilirsiniz. Tabi bu karşılık olayı hakimiyete göre değişebilir, benim için Pandas fonksiyonlarının SQL karşılıkları desem yeridir. 🙃

Pandas, verileri dataframe yapısında kullanabilmek ve işleyebilmek* için oluşturulmuş bir python kütüphanesidir, SQL ise veritabanları için kullanılan genel bir dildir. Çoğu geliştiricinin alet çantasında yer alan SQL, oldukça popüler aranan anahtar kelimeler arasında yer almaktadır. SQL’in gerekliliği verinin çıkış noktası düşünüldüğünde, olsa iyi olurdan ziyade zorunlu listesinde yer alması bekleniyor. Ama çoğu Pandas kullanıcısı gibi bende şunu sorguluyorum, veri bilimi özellinde birkaç metrik dışında SQL’e ihtiyacımız ne kadar? Bu sorunun cevabı bende yok 😬, belki de bu karşılaştırma tamamen yersiz de olabilir, ama sizlere SQL sorgularının rahatlıkla Pandas üzerinde derlenebileceğini göstermek istiyorum. Ayrıca SQL bilgim, SELECT, FROM ve WHERE düzeyinde olduğunu belirtmek isterim, örneklerim kompleks SQL sorguları haricinde daha basit ve temel syntax’lar üzerine olacaktır.

Öncelikle olmazsa olmazlarımızı import edelim; yüklediğimiz kütüphanelerden Pandas burada bulunma amacımız, Numpy ise birkaç matematik işlemi için kullanılacaktır. Karşılaştırmayı meşhur Titanik verisi üzerinden, dataframe ve tablomuzun aynı isimde olduğunu varsayarak başlıyorum. 🤨

import pandas as pd
import numpy as np

Veri üzerinde ilk 3 satırı gözlemlemek için aşağıdaki kodları kullanabiliriz. Son satırları görmek için tail() fonksiyonuyla sorgulama yapmalıyız. Aşağıdaki örneklerde de göreceğiniz gibi SQL sorgularının çoğunda LIMIT 3 yer almaktadır, amacım Pandas üzerinde bütün satırları gözlemlememek için kullandığım head(3) fonksiyonunun birebir karşılığını yazmaktır.

*SQL ve Pandas kodlarını, bütünlüğü korumak adına aynı blok içerisinde yer verdim. 😔

#SQL------------------------
SELECT * FROM df
LIMIT 3;
#Pandas---------------------
df.head(3)

SELECT

SQL'de seçim yapabilmek için virgül ile ayrılmış sütun listesini sorgulanırdı, bütün sütunlar için * işareti kullanılırdı. Pandas'da ise dataframe içerisine yazdığımız liste ile çağrılmaktadır. Liste hazırlanmadan çağrıldığında SQL'in * ile aynı sorguyu gerçekleştirir ve tüm sütunları listeler.

#SQL------------------------
SELECT Survived, Age, Fare, Embarked FROM df
LIMIT 3;
#Pandas---------------------
df[['Survived', 'Age', 'Fare', 'Embarked']].head(3)

WHERE

SQL'de filtreleme yapmak için WHERE kullanırken, Pandas bool değişkenlerini index ederek filtre etmektedir. Pandas'ın çalışmasına göre, seriyi True/False olarak süzgeçten geçirir ve dış seçilim ile sadece True olanlar yazdırılır.

#SQL------------------------
SELECT * FROM df
WHERE Embarked = 'S'
LIMIT 3;
#Pandas---------------------
df[df['Embarked'] == 'S'].head(3)

AS

Sütunlar arasında yaptığımız işlemi, yeni oluşturduğumuz sütuna yazdırabiliriz. Ayrıca Pandas üzerinde söz dizimi için farklı alternatifler mevcuttur. Aşağıda bulunan iki farklı kod için aynı çıktılar elde edilmektedir.

#SQL------------------------
SELECT *, SibSp+Parch AS Family_Size FROM df
LIMIT 3;
#Pandas---------------------
df.assign(Family_Size = lambda x: x.SibSp + x.Parch).head(3)
df['Family_Size'] = df['SibSp']+ df['Parch'] #alternatif
df.head(3)

OR, AND, NOT

SQL'de olduğu gibi Pandas için AND (&) ve OR (|) çoklu koşul yapabilmek için kullanılabilir. Bu koşullu fonksiyonlar arasında büyüklük-küçüklük veya değil seçenekleri bulunmaktadır.

#SQL------------------------
SELECT * FROM df
WHERE Survived = 5 OR Age >= 45
LIMIT 3;
#Pandas---------------------
df[(df['Survived'] == 1) | (df['Age'] >= 45)].head(3)

NULL

Pandas üzerinde notna()ve isna() ile boş hücre kontrolü yapabiliriz.

#SQL------------------------
SELECT * FROM df
WHERE Cabin IS NULL
LIMIT 3;
#Pandas---------------------
df[df['Cabin'].isna()].head(3)

GROUPBY

SQL ile benzer şekilde adlandırılan yöntem ile veri kümesi grup edilerek bazı fonksiyonlar uygulanır.

#SQL------------------------
SELECT Sex, COUNT(*) FROM df
GROUP BY Sex;
#Pandas---------------------
df.groupby('Sex').size()

AVG, COUNT, SUM

Belirtilen sütun için çeşitli fonksiyonlar uygulanabilmektedir. Pandas'ta syntax'lar farklılık gösterebilir, ayrıca min-max'da aynı yöntemle uygulanabilir.

#SQL------------------------
SELECT Sex, Survived, COUNT(*), AVG(Age) FROM df
GROUP BY Sex, Survived;
#Pandas---------------------
df.groupby(['Sex', 'Survived']).agg({'Age': [np.size, np.mean]})

ORDERBY

Pandas üzerinde sıralama yaparken, varsayılan olarak artan bir parametre kullanır, tersi için ascending=Falseparametresi yeterli olacaktır.

#SQL------------------------
SELECT * FROM df
ORDER BY Age
LIMIT 3;
#Pandas---------------------
df.sort_values(['Age']).head(3)

UPDATE

Orjinal veride bazı düzeltmeler yapmak istediğimizde eşitlik = yardımımıza koşuyor.

#SQL------------------------
UPDATE df
SET Age = 1
WHERE Age < 1;
#Pandas---------------------
df.loc[df['Age'] < 1, 'Age'] = 1

DELETE

Veriden bazı satırları veya sütunları çıkarmak istediğimizde filtre edip eşitlemek veya drop etmek yeterli olacaktır.

#SQL------------------------
DELETE FROM df
WHERE Age > 70;
#Pandas---------------------
df = df.loc[df['Age'] < 70]
df = df.drop(df[df['Age'] > 70].index) #alternatif

LIKE

Belirtilen kalıbı aramak için regex kurallarını kullanmaktadır. Regex düşünülünce, burada kullanılan alternatifler çoğaltılabilir.

#SQL------------------------
SELECT * FROM df
WHERE Name LIKE 'H%'
LIMIT 3;
#Pandas---------------------
df[df.Name.str.contains('^H', na=False)].head(3)

JOIN

Pandas üzerinde birleştirmek için alternatifler bulunmaktadır. Örneğimizde INNER JOIN için kodlar yazdırılmıştır, LEFT,RIGHT,OUTER sorguları için Pandas parametrelerinde ufak değişiklikler yeterli olacaktır. Konu hakkında daha fazlasını merak edenler için buraya link bırakıyorum.

df1 = pd.DataFrame({'key1': ['A', 'B', 'C', 'D'],
'value1': np.random.randn(4)})
df2 = pd.DataFrame({'key2': ['B', 'D', 'D', 'E'],
'value2': np.random.randn(4)})
#SQL------------------------
SELECT * FROM df1
INNER JOIN df2 ON df1.key1 = df2.key2;
#Pandas---------------------
pd.merge(df1, df2, on='key')

UNION

Dataframe üzerine başka verileri ekleyebiliriz, bu yöntem için yatay axis=1ve dikey axis=0 ekleme olarak alternatif parametreler mevcuttur.

#SQL------------------------
SELECT key1, value1 FROM df1
UNION ALL
SELECT key2, value2 FROM df2;
#Pandas---------------------
pd.concat([df1, df2]).drop_duplicates()

Oldukça büyük ve güçlü bir kütüphane olan Pandas 🚀 çok daha karmaşık sorgular yazılabilir, hatta kendi içinde bolca alternatif yazımları bile bulunmaktadır. Ancak içerikte yer alan temel SQL karşılıklarını gösterebilmek için yazdıklarımın yeterli olduğunu düşünüyorum. Pandas, verileri başarılı bir şekilde işleyebilmek ve keşfedebilmek için oldukça fonksiyonel seçenekler sunmaktadır. Daha fazlasını merak ediyorsanız, Pandas’ı keşfetmeye buradan başlayabilirsiniz.

Severek kullandığım Pandas için söyleyeceklerim bunlar, kaynak olarak Pandas dokümanı ile w3schools kullanıldı ve keyifle hazırladığım bu içeriği okuduğunuz için teşekkür ederim. 🦕

Sağlıkla ve sevgilerle 👋

--

--