Pandas, veri analizini kolaylaştırmak için Python veri bilimcilerinin fiili araç kutusudur: Örneğin analizlere başlamadan önce veriyi toplamak, keşfetmek ve biçimlendirmek için kullanabilirsiniz. Pandas, çok sayıdaki G/Ç ve kullanışlı veri işleme fonksiyonlarıyla bu adımları son derece kolaylaştırır. Dahası, bu eğitimde ilerleyen bölümlerde öğreneceğiniz gibi, görselleştirme yetenekleri de vardır ( matplotlib aracılığıyla).
Pandas veri yapıları çok güçlü ve esnek olsa da, özellikle yeni başlayanlar için analizinizi kolaylaştırmaktan ziyade zorlaştırabilecek bazı karmaşıklıklar da içerir. Bu eğitimde, kendinizi dertten kurtarıp daha idiomatik Pandas kodu yazmayı nasıl başarabileceğinize odaklanacaksınız. Veriyi nasıl yükleyeceğinizi, keşfedeceğinizi ve temizleyeceğinizi öğrenmenin yanı sıra aşağıdaki beş konuyu da inceleyeceksiniz:
Elbette bu eğitim hiçbir şekilde kapsamlı değildir; Pandas paketi çok zengindir ve Pandas kodunuzu daha idiomatik hâle getirmenin kuşkusuz başka yolları da vardır.
Daha fazla beklemeden başlayalım!
İlk Adım: Veriyi Yükleyin ve Keşfedin
Her zaman olduğu gibi, veri analizi veriyi yükleme ve keşfetmeyle başlar. Bu bölüm, read_csv() fonksiyonunu kullanarak dünya üniversite sıralamalarını yükleyeceğiniz ve ardından head() ve describe() fonksiyonlarıyla verinizi hızlıca inceleyeceğiniz bir ısınma turudur. Pandas’a tam bir girişle ilgileniyorsanız, DataCamp’in üç bölümlük Pandas kursunu, Pandas Foundations ile başlayarak almayı düşünebilirsiniz.
Tüm bunları zaten biliyorsanız, bu bölümü atlayıp Pandas ile daha idiomatik şekilde nasıl indeksleme yapabileceğinizi görebilirsiniz.
Paketlerin içe aktarılması
Başlamak için, veri bilimi için alışılmış Python paketlerini içe aktaralım. Tahmin edebileceğiniz gibi, Pandas da bunların arasında.
# If you're working with a notebook, don't forget to use Matplotlib magic! %matplotlib inline
# Import pandas under the alias pd import pandas as pd # Import seaborn under the alias sns import seaborn as sns # Set the Seaborn theme if desired sns.set_style('darkgrid')Altyapı:
Ayrıca watermark paketini de kullanabilirsiniz: not defterinizi daha yeniden üretilebilir kılan güzel bir araçtır. Yeniden üretilebilir çalışma, ekip arkadaşlarınızla iş birliği yaparken çok önemlidir. Gelecekteki kendiniz de size bunun için teşekkür edecektir! Yeniden üretilebilir veri bilimi hakkında daha fazla bilgiyi buradan okuyabilirsiniz.
Veri
Bu eğitime başlayabilmek için “gerçek” dünya verisi de almanız gerekecek. Bu eğitimde, Kaggle’dan bir veri setiyle çalışacaksınız. Kaggle ile aşina değilseniz, en büyük veri bilimi ve makine öğrenimi topluluklarından biridir. Ayrıca, temelleri öğrendikten sonra veri bilimi hakkında daha fazla bilgi edinmek için iyi bir yerdir.
Yukarıda belirtildiği gibi, Pandas’ın farklı veri kaynaklarından veri okumak için birçok kullanışlı yöntemi vardır (bunun hakkında daha fazlasını buradan öğrenebilirsiniz). Veri CSV formatında olduğundan, .read_csv metodunu kullanacağız. Ancak başlamadan önce, veriyi Kaggle’dan indirmeniz gerekir (veya bir hesap oluşturmak istemiyorsanız kod deposundaki data klasöründen alabilirsiniz).
Veriyi aldıktan sonra, farklı csv dosyalarını içeren bir data klasörünüz olmalıdır.
# Import Times Higher Education World University Rankings data
times_df = pd.read_csv('data/timesData.csv', thousands=",")# Import Academic Ranking of World Universities data
shanghai_df = pd.read_csv('data/shanghaiData.csv')Altyapı:
Veriyi hızlıca inceleme
DataCamp’in Keşifsel Veri Analizi eğitiminde öğrendiğiniz gibi, Pandas DataFrame’leri hızlıca incelemek için bazı yöntemler sunar; yani ilk n satırı görmek için .head() (n varsayılan olarak 5’tir) ve hızlı bir istatistiksel özet almak için .describe().
Aşağıdaki kod satırlarını çalıştırarak bu fonksiyonları tazeleyin. Veriler sizin için zaten times_df ve shanghai_df değişkenlerine yüklendi:
# Return the first rows of `times_df`
times_df.____()
# Describe `times_df`
times_df.describe()
# Return the first rows of `shanghai_df`
shanghai_df.head()
# Describe `shanghai_df`
shanghai_df.________()
Artık verinizi yüklediğinize göre, veriyi Pandas ile idiomatik bir şekilde nasıl işleyebileceğinizi düşünmeye başlayabilirsiniz!
İdiomatik Pandas Kodu İçin İpuçlarımız
1. İndeksleme
Öncelikle, daha idiomatik Pandas kodu yazmak, indekslemenin gücünden yararlanmak demektir. İndeksleme, DataFrame’inizden alt kümeler seçmeniz anlamına gelir.
Pandas’a yeni başlarken, indekslerin nasıl çalıştığına alışmak için biraz zamana ihtiyaç duyabilirsiniz. Aslında daha önce (Python) listeleriyle çalıştıysanız, köşeli parantezleri [] iki nokta : ile birlikte kullanarak öğe seçmeye zaten aşina olabilirsiniz. Bu yöntem DataFrame’lerde de işe yarar.
Buna ek olarak, bir alt küme DataFrame seçmenin iki başka, daha idiomatik yolu daha vardır: iloc ve loc:
loc etiket tabanlıdır. Yani loc[2] yazarsanız, indeksi 2 olarak etiketlenmiş DataFrame değerlerini arıyorsunuz demektir.
iloc konum tabanlıdır. Yani iloc[2] yazarsanız, indeksi 2 olan konumdaki DataFrame değerlerini arıyorsunuz demektir.
Aşağıdaki DataCamp Light bölümünde IPython konsoluna times_df.loc[2] ve times_df.iloc[2] yazarak aralarındaki farkı deneyin. Ardından, aşağıdaki alıştırmayı loc, iloc ve geleneksel köşeli parantezler yardımıyla çözmeyi deneyin!
# Retrieve the total score of the first row
print(times_df.loc[0, '___________'])
# Retrieve rows 0 and 1
print(times_df[_:_])
# Retrieve the values at columns and rows 1-3
print(times_df.iloc[1:4,1:4])
# Retrieve the column `total_score`
print(times_df['__________'])
Elbette, keşfiniz verinizin satır ve sütunlarından yalnızca alt kümelemeye ya da seçim yapmaya indirgenmek zorunda değil. loc ve iloc’u örneğin boole dizileriyle birleştirdiğinizde işler epey ilginçleşebilir.
Bu, sütunlara ya da indekslemeye göre seçim yapmanın biraz ötesine geçer; verinizi sorgulamak gibidir!
# Are the last entries after 2006?
print(shanghai_df.loc[:-10, 'year'] > 2006)
# Was the alumni count higher than 90 for the first ten universities?
print(shanghai_df.loc[0:11, 'alumni'] > 90)
loc ve iloc verinizi indekslemek için harikadır, ancak art arda iki küme köşeli parantez kullanmaya başladığınızda dikkatli olun! Pandas bir görünümün kopyasını döndürebilir ve böyle durumlarda neyle çalışmaya devam ettiğinizi bilemeyebilirsiniz! Bu yüzden, loc veya iloc ile birlikte iki küme köşeli parantez kullanıyorsanız iki kez düşünün.
Not: Verinizi sorgulamak için, Pandas ayrıca verinizi hızlıca incelemenize yarayan bir query() fonksiyonu da sunar (sürüm 0.13’ten beri mevcuttur). Örneğin, total_score’u 50’nin biraz altında olan üniversiteleri görmek için bir sorgu yazabilirsiniz:
# Query `shanghai_df` for universities with total score between 40 and 50
averge_schools = shanghai_df.query('total_score > __ and total_score < __')
# Print the result
print(average_schools)
Elbette, verinizi sorgulama söz konusu olduğunda daha birçok olasılık var! Neden bazı sorgular üretip yukarıdaki DataCamp Light bölümünün IPython konsolunda test etmiyorsunuz?
İlham arıyorsanız, ulusal sıralaması birinci olan üniversiteleri ve dünya sıralaması birinci olan üniversiteleri döndüren sorguları deneyebilirsiniz. Ayrıca üniversitelerin mezun sayıları hakkında da sorgular yazabilirsiniz.
Sorguları nasıl oluşturacağınız konusunda kaybolduysanız, aşağıdaki örneklere göz atın:
shanghai_df.query("national_rank == 1 and world_rank == 1")
shanghai_df.query("alumni < 20")Altyapı:
2. Metot zincirleme
Metot zincirleme, Pandas’a özgü bir pratiktir; ancak Python veri işleme paketine yeni başlarken tam olarak nasıl çalıştığı ilk bakışta anlaşılmayabilir. Temelde bir nesne üzerinde art arda metot çağırmaktır.
Bu bölümde, pipe() ile veri boru hatları oluşturarak metot zincirlemeyi daha ayrıntılı inceleyeceksiniz.
# Extract info
def extract_info(input_df, name):
df = input_df.copy()
info_df = pd.DataFrame({'nb_rows': df.shape[0], 'nb_cols': df.shape[1], 'name': name}, index=range(1))
return info_df
# Gather all info
all_info = pd.concat([times_df.pipe(extract_info, 'times'), shanghai_df.pipe(extract_info, 'shanghai')])
Gördüğünüz gibi, veri setleri epey farklı. İşte bazı farklar:
Times veri setinde 14 sütun varken Shanghai veri setinde 11 sütun var
Times veri setinde 2603 satır varken Shanghai veri setinde 4897 satır var
Shanghai veri setinde eksik olan önemli bir sütun üniversitenin ülkesidir. Gerekirse bu bilgiyi ileride Times veri setinden alacaksınız.
Dolayısıyla her iki DataFrame’i de kullanabilmek için yalnızca ortak sütunları seçmemiz gerekecek. Umuyoruz ki bu ortak sütunların içerikleri benzerdir.
total_score: Sıralamayı belirlemek için kullanılan puan. Kaggle açıklama sayfasında belirtildiği gibi, bunlar aralık sıralamaları (yani iki değer arasında) ve eşit sıralamalar içerir (= işareti bulunur)
university_name: Üniversite adı
world_rank: Üniversitenin dünya sıralaması
year: Sıralamanın yapıldığı yıl
Her iki veriyi birleştirebilmek için önce biraz temizlik yapmamız gerekiyor. Ardından veriyi temizlemek için tam boru hattını şimdi uygulayın:
# Clean up the `world_rank
def clean_world_rank(input_df):
df = input_df.copy()
df.world_rank = df.world_rank.str.split('-').str[0].str.split('=').str[0]
return df
# Assign the common years of `shanghai_df` and `times_df` to `common_years`
common_years = set(shanghai_df.year) & set(times_df.year)
# Print `common_years`
print(common_years)
# Filter years
def filter_year(input_df, years):
df = input_df.copy()
return df.query('year in {}'.format(list(years)))
# Clean `times_df` and `shanghai_df`
cleaned_times_df = (times_df.loc[:, common_columns]
.pipe(filter_year, common_years)
.pipe(clean_world_rank)
.assign(name='times'))
cleaned_shanghai_df = (shanghai_df.loc[:, common_columns]
.pipe(filter_year, common_years)
.pipe(clean_world_rank)
.assign(name='shanghai'))
Bu eğitimde .pipe metodunu çok kullandığımı fark etmişsinizdir. R dünyasından geliyorsanız muhtemelen (bir şekilde) aşinasınızdır.
Bu, Pandas’ın (0.16.2 sürümünden beri) kullanışlı yeni bir metodudur ve işlemleri zincirlemenize, dolayısıyla ara DataFrame’lere duyulan ihtiyacı ortadan kaldırmanıza olanak tanır. Kodunuz daha okunaklı hâle gelir.
Aslında bu operatör olmadan, df.pipe(f).pipe(g).pipe(h) yazmak yerine h(g(f(df))) yazmanız gerekirdi. İç içe fonksiyon sayısı arttıkça bunu takip etmek zorlaşır.
Konu hakkında daha fazla bilgi için şu blog yazısını okumanızı şiddetle öneririm.
Her iki DataFrame de temizlendiğine göre, bunları tek bir DataFrame’de birleştirebiliriz. Ayrıca eksik verileri temizlemeyi unutmayın:
# Compose `ranking_df` with `cleaned_times_df` and `cleaned_shanghai_df`
ranking_df = pd.concat([cleaned_times_df, cleaned_shanghai_df])
# Calculate the percentage of missing data
missing_data = 100 * pd.isnull(ranking_df.total_score).sum() / len(ranking_df)
# Drop the `total_score` column of `ranking_df`
ranking_df = ranking_df.drop('total_score', axis=1)
total_score sütununda yaklaşık %38 oranında eksik veri olduğundan, bu sütunu .drop metoduyla bırakmak daha iyi olacaktır.
3. Bellek optimizasyonu
Pandas kodunuzu daha “idiomatik” yapmanın üçüncü yolu —bu durumda “performant” olmaya daha yakın— bellek kullanımını optimize etmektir. Özellikle metot zincirleme kullanarak veri boru hatları oluşturmaya başladığınızda, belleğin hatlarınızın ne kadar hızlı çalıştığı üzerinde büyük bir etkisi olabileceğini göreceksiniz. Tüm bunları burada daha ayrıntılı göreceksiniz.
Bu küçük veri seti için biraz abartı olabilir; ancak bellek kullanımını optimize etmek adına bazı sütunları belirli tiplere dönüştürmek genellikle iyi bir pratiktir. Başlamak için, ranking_df için ne kadar bellek ayrıldığını .info metodu ile bulalım.
# Print the memory usage of `ranking_df`
ranking_df.____()
# Print the deep memory usage of `ranking_df`
ranking_df.info(memory_usage="deep")
Kodun ilk satırının sonucu bize verinin 144 KB yer kapladığını söylüyor. Ancak .info metodunun argümanlarına bakıldığında, varsayılan olarak None olan memory_usage adlı isteğe bağlı bir argüman olduğu görülür. memory_usage argümanını deep olarak ayarladığınızda ne olur?
Yeni bellek ayak izi, ilk yanıtınızın 6 —daha doğrusu 5,6— katıdır.
Burada ne oldu?
Bellek tahminindeki fark, “deep” bayrağı açık değilken Pandas’ın object dtype’ı için bellek tüketimini tahmin etmemesinden kaynaklanır. Bu (Python) veri tipi, diğer numpy tarafından optimize edilmiş dtype’lardan daha fazla alan kaplar. Bu nedenle object tiplerini daha uygun tiplere dönüştürmek (örneğin kategorik verilerle çalışırken category) önerilir.
Hadi yapalım!
defmemory_change(input_df, column, dtype):
df = input_df.copy()
old =round(df[column].memory_usage(deep=True)/1024,2)# In KB
new =round(df[column].astype(dtype).memory_usage(deep=True)/1024,2)# In KB
change =round(100*(old - new)/(old),2)
report =("The inital memory footprint for {column} is: {old}KB.\n""The casted {column} now takes: {new}KB.\n""A change of {change} %.").format(**locals())return report
print(memory_change(ranking_df,'world_rank','int16'))print(memory_change(ranking_df,'university_name','category'))print(memory_change(ranking_df,'name','category'))Altyapı:
Artık örneğin world_rank’i int16’ya çevirmenin belleği daha verimli kullanacağını bildiğinize göre, bu değişiklikleri gerçekten uygulamanın zamanı geldi. Bunu yapmak için astype() fonksiyonunu kullanabilirsiniz. Son olarak bellek kullanımınızın şimdi nasıl göründüğünü tekrar kontrol edin:
# Cast `world_rank` as type `int16`
ranking_df.world_rank = ranking_df.world_rank._______('int16')
# Cast `unversity_name` as type `category`
ranking_df.university_name = ranking_df.university_name.astype('category')
# Cast `name` as type `category`
ranking_df.name = ranking_df.____.astype('category')
# Double check the memory usage after type casting
ranking_df.info(memory_usage='deep')
Çok daha iyi. year sütununu int32’ye indirerek daha da optimize edebilirsiniz.
4. GroupBy
Artık iyi biçimlendirilmiş bir veri kümesine sahip olduğumuza göre (yani düzenli durumda) ve bellek ayak izi optimize edildiğine göre veri analizi başlayabilir.
Cevaplamak isteyebileceğiniz bazı sorular var:
Yıllar boyunca her bir sıralama sistemine göre en iyi 5 üniversite hangileri?
Bu sıralamalar her yıl ne kadar farklı?
Hadi ilk soruyu, önceki bölümlerde gördüğünüz daha idiomatik Pandas ipuçlarını kullanarak ele alalım!
Başlamadan önce, ‘Massachusetts Institute of Technology (MIT)’ ve ‘Massachusetts Institute of Technology’ aynı üniversitenin iki farklı kaydıdır. Bu nedenle, ilk adı ikincisiyle değiştirin.
Bu gibi durumlarda, bu eğitimde daha önce gördüğünüz loc fonksiyonunun özellikle kullanışlı olduğunu unutmayın!
# Query for the rows with university name 'Massachusetts Institute of Technology (MIT)'
print(ranking_df._____("university_name == 'Massachusetts Institute of Technology (MIT)'"))
# Localize the rows with the MIT university name and replace value
ranking_df.loc[lambda df: df.university_name == 'Massachusetts Institute of Technology (MIT)', 'university_name'] = 'Massachusetts Institute of Technology'
# Print `ranking_df`
print(__________)
Her bir sıralama sistemi için yıllar boyunca en iyi 5 (genel olarak n) üniversiteyi bulmak için, işte sözde kodla nasıl yapılacağı:
Her yıl (year sütununda) ve her sıralama sistemi (name sütununda)) için:
Belirli yıl ve sıralama sistemi için verinin alt kümesini seçin
En iyi 5 üniversiteyi seçin ve bir listede saklayın
Sonucu, anahtarı (year, name) olan ve değeri üniversitelerin (azalan sırada) listesi olan bir sözlükte saklayın
Uygulayalım.
# Load in `itertools`
import itertools
# Initialize `ranking`
ranking = {}
for year, name in itertools.product(common_years, ["times", "shanghai"]):
s = (ranking_df.loc[lambda df: ((df.year == year) & (df.name == name)
& (df.world_rank.isin(range(1,6)))), :]
.sort_values('world_rank', ascending=False)
.university_name)
ranking[(year, name)] = list(s)
# Print `ranking`
print(ranking)
Artık bu sıralama sözlüğü elimizdeyken, yıllar boyunca her iki sıralama yönteminin ne kadar (yüzde olarak) farklılaştığını bulalım: Seçilen ilk 5 üniversite aynıysa, sıralamaları aynı olmasa bile iki küme %100 benzer kabul edilir.
# Import `defaultdict`
from collections import defaultdict
# Initialize `compare`
compare = defaultdict(list)
# Initialize `exact_similarity` and `set_similarity`
exact_similarity = {}
set_similarity = {}
for (year, method), universities in ranking.items():
compare[year].append(universities)
for year, ranks in compare.items():
set_similarity[year] = 100 * len(set(ranks[0]) & set(ranks[1])) / 5.0
# Print `set_similarity`
print(set_similarity)
Gördüğünüz gibi bu zahmetliydi. Daha iyi, daha idiomatik bir Pandas yolu var mı?
Elbette var! Öncelikle, her yıl ve sıralama yöntemi için yalnızca en iyi 5 üniversiteyi tutacak şekilde sıralama DataFrame’ini filtreleyin. Sonucu head() fonksiyonuyla da kontrol edin:
# Construct a DataFrame with the top 5 universities
top_5_df = ranking_df.loc[lambda df: df.world_rank.isin(range(1, 6)), :]
# Print the first rows of `top_5_df`
top_5_df.____()
Artık üzerinde çalışmak için doğru DataFrame elinizde olduğuna göre, yukarıda tanımlanan küme benzerliğini kullanarak her iki sıralama yöntemini karşılaştırmak için .groupby metodunu kullanalım.
# Compute the similarity
def compute_set_similarity(s):
pivoted = s.pivot(values='world_rank', columns='name', index='university_name').dropna()
set_simlarity = 100 * len((set(pivoted['shanghai'].index) & set(pivoted['times'].index))) / 5
return set_simlarity
# Group `top_5_df` by `year`
grouped_df = top_5_df._______('year')
# Use `compute_set_similarity` to construct a DataFrame
setsimilarity_df = pd.DataFrame({'set_similarity': grouped_df.apply(compute_set_similarity)}).reset_index()
# Print the first rows of `setsimilarity_df`
setsimilarity_df.____()
Yukarıdakiyle aynı sonuçları, daha az zahmetle elde edersiniz.
5. Görselleştirme
Veri setleriniz üzerinde bazı başlangıç analizlerinden geçtiğinize göre, verinizi görsel olarak da keşfetmenin zamanı geldi. Daha idiomatik Pandas kodu, Pandas’ın Matplotlib paketiyle çizim entegrasyonundan yararlanmanız anlamına da gelir. Bu sayede kısa sürede harika grafikler oluşturursunuz!
Bu bölüm için, Matplotlib ve Seaborn ile bazı temel görselleştirmeler yapmak üzere times_df ve shanghai_df veri setlerine geri döneceksiniz.
# Plot a scatterplot with `total_score` and `alumni`
shanghai_df.plot.scatter('total_score', 'alumni', c='year', colormap='viridis')
plt.show()
Yukarıdaki grafik, alumni sütunu için bazı 0 değerleri olduğunu anında gösterir. Verinizi keşfederken kesinlikle dikkate almanız gereken bir durumdur: veri profilleme yardımıyla bu 0 değerleri görebilir ve bunlarla başa çıkabilirsiniz. Bunun hakkında daha fazla bilgi edinmek isterseniz, DataCamp’in Veri Profilleme Eğitimine göz atın.
Ya da veri setinizde yeri olmayan değerleriniz varsa, bunları basitçe NaN ile değiştirebilir ve ardından çizimi zorlaştıracak sütunlardaki tüm NaN değerlerini kaldırabilirsiniz. Bunun, verinizi hızlıca ayarlamanın bir yolu olduğunu ve veri kalitenizi iyileştirmek için muhtemelen daha kapsamlı bir veri profilleme adımına ihtiyaç duyacağınızı unutmayın; çünkü aşağıdaki grafikte num_students sütunu için hâlâ 0 değerleri görüyorsunuz:
# Replace `-` entries with NaN values
times_df['total_score']= times_df['total_score'].replace("-", "NaN").astype('float')
# Drop all rows with NaN values for `num_students`
times_df = times_df.dropna(subset=['num_students'], how='all')
# Cast the remaining rows with `num_students` as int
times_df['num_students'] = times_df['num_students'].astype('int')
# Plot a scatterplot with `total_score` and `num_students`
times_df.plot.scatter('total_score', 'num_students', c='year', colormap='viridis')
plt.show()
Elbette verinizi görselleştirmek için kendinizi Matplotlib ile sınırlamak zorunda değilsiniz. Seaborn gibi verinizi hızlıca görselleştirmenizi sağlayan başka kütüphaneler de var.
Seaborn çizim aracı, esas olarak görsel olarak çekici istatistiksel grafikler oluşturmak için kullanılır (resmi sitede belirtildiği gibi). Aslında Matplotlib’in 2.0 sürümünden önce güzel grafikler oluşturmak zahmetliydi (yine de mümkündü).
Pandas ile Seaborn’un birleşimi, görselleştirmeler aracılığıyla veriniz üzerinde hızlıca yineleme yapmanıza da olanak tanır.
Hadi bazı örnekleri keşfedelim!
Aşağıdaki grafiğe bir göz atın: burada belirli bir ülkenin verinizde kaç kez göründüğünü sayıyorsunuz, ilk on gözlemi alıyorsunuz ve çubuk grafiğini çizerken sayımların en yüksekten en düşüğe sıralandığından emin oluyorsunuz:
Ardından bu ülkeleri ve ortalama puanlarını çizebilirsiniz:
# Barplot with `country` and `total_score`
sns.barplot(x='country', y='total_score', data=times_df_filtered)
sns.despine()
plt.show()
Grafikleriniz oldukça karmaşık da olabilir. Aşağıdaki pairplot’a bakın; bir veri setindeki ikili ilişkileri daha net göstermek için tasarlanmıştır:
import numpy as np
np.seterr(invalid='ignore')
sns.pairplot(times_df, hue='country')
plt.show()Altyapı:
Benzer şekilde, en iyi 5 ülke için yıllar içinde total_score’daki değişime dair içgörüler veren FacetGrid ve regplot birleşimine göz atabilirsiniz:
# Filter out rows with NaN entry for `total_score`
times_df_filtered = times_df_filtered.dropna(subset=['total_score'], how='all')
g = sns.FacetGrid(times_df_filtered, col='country', hue='country')
g.map(sns.regplot, 'year', 'total_score').set(xlim=(2010, 2015), ylim=(0,100))
g.fig.subplots_adjust(wspace=.2)
Son olarak, verinizi keşfederken bir korelasyon grafiği de işinize yarayabilir. Bunu yapmak için Seaborn’daki heatmap() fonksiyonunu kullanabilirsiniz:
import matplotlib.pyplot as plt
sns.set(style="white")
# Compute the correlation matrix
corr = times_df.corr()
# Generate a mask for the upper triangle
mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))
# Generate a custom diverging colormap
cmap = sns.diverging_palette(220, 10, as_cmap=True)
# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3,
square=True, linewidths=.5, ax=ax)
plt.show()
Bu görselleştirmelerle daha da devam edebilirsiniz, bu yüzden belki de şimdilik durmak en iyisi :)
Sonraki Adımlar
Şimdilik bu kadar; Pandas ile çalışırken orta seviye teknikleri ve özellikle daha idiomatik Pandas kodu yazmayı öğrenmekten keyif aldığınızı umuyorum.
Bu blog yazısını beğendiyseniz ve Pandas’ta performans konusuna daha derinlemesine dalmak isterseniz, aşağıdaki ek materyalleri şiddetle öneririm:
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Pandas, veri analizini kolaylaştırmak için Python veri bilimcilerinin fiili araç kutusudur: Örneğin analizlere başlamadan önce veriyi toplamak, keşfetmek ve biçimlendirmek için kullanabilirsiniz. Pandas, çok sayıdaki G/Ç ve kullanışlı veri işleme fonksiyonlarıyla bu adımları son derece kolaylaştırır. Dahası, bu eğitimde ilerleyen bölümlerde öğreneceğiniz gibi, görselleştirme yetenekleri de vardır (
matplotlibaracılığıyla).Pandas veri yapıları çok güçlü ve esnek olsa da, özellikle yeni başlayanlar için analizinizi kolaylaştırmaktan ziyade zorlaştırabilecek bazı karmaşıklıklar da içerir. Bu eğitimde, kendinizi dertten kurtarıp daha idiomatik Pandas kodu yazmayı nasıl başarabileceğinize odaklanacaksınız. Veriyi nasıl yükleyeceğinizi, keşfedeceğinizi ve temizleyeceğinizi öğrenmenin yanı sıra aşağıdaki beş konuyu da inceleyeceksiniz:
Elbette bu eğitim hiçbir şekilde kapsamlı değildir; Pandas paketi çok zengindir ve Pandas kodunuzu daha idiomatik hâle getirmenin kuşkusuz başka yolları da vardır.
Daha fazla beklemeden başlayalım!
İlk Adım: Veriyi Yükleyin ve Keşfedin
Her zaman olduğu gibi, veri analizi veriyi yükleme ve keşfetmeyle başlar. Bu bölüm,
read_csv()fonksiyonunu kullanarak dünya üniversite sıralamalarını yükleyeceğiniz ve ardındanhead()vedescribe()fonksiyonlarıyla verinizi hızlıca inceleyeceğiniz bir ısınma turudur. Pandas’a tam bir girişle ilgileniyorsanız, DataCamp’in üç bölümlük Pandas kursunu, Pandas Foundations ile başlayarak almayı düşünebilirsiniz.Tüm bunları zaten biliyorsanız, bu bölümü atlayıp Pandas ile daha idiomatik şekilde nasıl indeksleme yapabileceğinizi görebilirsiniz.
Paketlerin içe aktarılması
Başlamak için, veri bilimi için alışılmış Python paketlerini içe aktaralım. Tahmin edebileceğiniz gibi, Pandas da bunların arasında.
Ayrıca
watermarkpaketini de kullanabilirsiniz: not defterinizi daha yeniden üretilebilir kılan güzel bir araçtır. Yeniden üretilebilir çalışma, ekip arkadaşlarınızla iş birliği yaparken çok önemlidir. Gelecekteki kendiniz de size bunun için teşekkür edecektir! Yeniden üretilebilir veri bilimi hakkında daha fazla bilgiyi buradan okuyabilirsiniz.Veri
Bu eğitime başlayabilmek için “gerçek” dünya verisi de almanız gerekecek. Bu eğitimde, Kaggle’dan bir veri setiyle çalışacaksınız. Kaggle ile aşina değilseniz, en büyük veri bilimi ve makine öğrenimi topluluklarından biridir. Ayrıca, temelleri öğrendikten sonra veri bilimi hakkında daha fazla bilgi edinmek için iyi bir yerdir.
Kullanacağınız veri seti World University Rankings’tir.
Yukarıda belirtildiği gibi, Pandas’ın farklı veri kaynaklarından veri okumak için birçok kullanışlı yöntemi vardır (bunun hakkında daha fazlasını buradan öğrenebilirsiniz). Veri
CSVformatında olduğundan,.read_csvmetodunu kullanacağız. Ancak başlamadan önce, veriyi Kaggle’dan indirmeniz gerekir (veya bir hesap oluşturmak istemiyorsanız kod deposundakidataklasöründen alabilirsiniz).Veriyi aldıktan sonra, farklı csv dosyalarını içeren bir
dataklasörünüz olmalıdır.Sonraki adımda, Times Higher Education World University Rankings (kısaca Times) ve Academic Ranking of World Universities (kısaca Shanghai) verileriyle çalışacaksınız.
dataklasöründe üçüncü bir sıralama sistemi daha vardır: CWUR; ancak çok daha az bilinir, bu yüzden şimdilik güvenle göz ardı edebilirsiniz.Veriyi hızlıca inceleme
DataCamp’in Keşifsel Veri Analizi eğitiminde öğrendiğiniz gibi, Pandas DataFrame’leri hızlıca incelemek için bazı yöntemler sunar; yani ilk
nsatırı görmek için.head()(nvarsayılan olarak 5’tir) ve hızlı bir istatistiksel özet almak için.describe().Aşağıdaki kod satırlarını çalıştırarak bu fonksiyonları tazeleyin. Veriler sizin için zaten
times_dfveshanghai_dfdeğişkenlerine yüklendi:Artık verinizi yüklediğinize göre, veriyi Pandas ile idiomatik bir şekilde nasıl işleyebileceğinizi düşünmeye başlayabilirsiniz!
İdiomatik Pandas Kodu İçin İpuçlarımız
1. İndeksleme
Öncelikle, daha idiomatik Pandas kodu yazmak, indekslemenin gücünden yararlanmak demektir. İndeksleme, DataFrame’inizden alt kümeler seçmeniz anlamına gelir.
Pandas’a yeni başlarken, indekslerin nasıl çalıştığına alışmak için biraz zamana ihtiyaç duyabilirsiniz. Aslında daha önce (Python) listeleriyle çalıştıysanız, köşeli parantezleri
[]iki nokta:ile birlikte kullanarak öğe seçmeye zaten aşina olabilirsiniz. Bu yöntem DataFrame’lerde de işe yarar.Buna ek olarak, bir alt küme DataFrame seçmenin iki başka, daha idiomatik yolu daha vardır:
ilocveloc:locetiket tabanlıdır. Yaniloc[2]yazarsanız, indeksi2olarak etiketlenmiş DataFrame değerlerini arıyorsunuz demektir.ilockonum tabanlıdır. Yaniiloc[2]yazarsanız, indeksi2olan konumdaki DataFrame değerlerini arıyorsunuz demektir.Aşağıdaki DataCamp Light bölümünde IPython konsoluna
times_df.loc[2]vetimes_df.iloc[2]yazarak aralarındaki farkı deneyin. Ardından, aşağıdaki alıştırmayıloc,ilocve geleneksel köşeli parantezler yardımıyla çözmeyi deneyin!Elbette, keşfiniz verinizin satır ve sütunlarından yalnızca alt kümelemeye ya da seçim yapmaya indirgenmek zorunda değil.
locve iloc’u örneğin boole dizileriyle birleştirdiğinizde işler epey ilginçleşebilir.Bu, sütunlara ya da indekslemeye göre seçim yapmanın biraz ötesine geçer; verinizi sorgulamak gibidir!
locveilocverinizi indekslemek için harikadır, ancak art arda iki küme köşeli parantez kullanmaya başladığınızda dikkatli olun! Pandas bir görünümün kopyasını döndürebilir ve böyle durumlarda neyle çalışmaya devam ettiğinizi bilemeyebilirsiniz! Bu yüzden,locveyailocile birlikte iki küme köşeli parantez kullanıyorsanız iki kez düşünün.Not: Verinizi sorgulamak için, Pandas ayrıca verinizi hızlıca incelemenize yarayan bir
query()fonksiyonu da sunar (sürüm 0.13’ten beri mevcuttur). Örneğin,total_score’u 50’nin biraz altında olan üniversiteleri görmek için bir sorgu yazabilirsiniz:Elbette, verinizi sorgulama söz konusu olduğunda daha birçok olasılık var! Neden bazı sorgular üretip yukarıdaki DataCamp Light bölümünün IPython konsolunda test etmiyorsunuz?
İlham arıyorsanız, ulusal sıralaması birinci olan üniversiteleri ve dünya sıralaması birinci olan üniversiteleri döndüren sorguları deneyebilirsiniz. Ayrıca üniversitelerin mezun sayıları hakkında da sorgular yazabilirsiniz.
Sorguları nasıl oluşturacağınız konusunda kaybolduysanız, aşağıdaki örneklere göz atın:
2. Metot zincirleme
Metot zincirleme, Pandas’a özgü bir pratiktir; ancak Python veri işleme paketine yeni başlarken tam olarak nasıl çalıştığı ilk bakışta anlaşılmayabilir. Temelde bir nesne üzerinde art arda metot çağırmaktır.
Bu bölümde,
pipe()ile veri boru hatları oluşturarak metot zincirlemeyi daha ayrıntılı inceleyeceksiniz.Gördüğünüz gibi, veri setleri epey farklı. İşte bazı farklar:
Dolayısıyla her iki DataFrame’i de kullanabilmek için yalnızca ortak sütunları seçmemiz gerekecek. Umuyoruz ki bu ortak sütunların içerikleri benzerdir.
Ortak sütunlar şunlardır:
total_score: Sıralamayı belirlemek için kullanılan puan. Kaggle açıklama sayfasında belirtildiği gibi, bunlar aralık sıralamaları (yani iki değer arasında) ve eşit sıralamalar içerir (=işareti bulunur)university_name: Üniversite adıworld_rank: Üniversitenin dünya sıralamasıyear: Sıralamanın yapıldığı yılHer iki veriyi birleştirebilmek için önce biraz temizlik yapmamız gerekiyor. Ardından veriyi temizlemek için tam boru hattını şimdi uygulayın:
Bu eğitimde
.pipemetodunu çok kullandığımı fark etmişsinizdir. R dünyasından geliyorsanız muhtemelen (bir şekilde) aşinasınızdır.Bu, Pandas’ın (0.16.2 sürümünden beri) kullanışlı yeni bir metodudur ve işlemleri zincirlemenize, dolayısıyla ara DataFrame’lere duyulan ihtiyacı ortadan kaldırmanıza olanak tanır. Kodunuz daha okunaklı hâle gelir.
Aslında bu operatör olmadan,
df.pipe(f).pipe(g).pipe(h)yazmak yerineh(g(f(df)))yazmanız gerekirdi. İç içe fonksiyon sayısı arttıkça bunu takip etmek zorlaşır.Konu hakkında daha fazla bilgi için şu blog yazısını okumanızı şiddetle öneririm.
Her iki DataFrame de temizlendiğine göre, bunları tek bir DataFrame’de birleştirebiliriz. Ayrıca eksik verileri temizlemeyi unutmayın:
total_scoresütununda yaklaşık %38 oranında eksik veri olduğundan, bu sütunu.dropmetoduyla bırakmak daha iyi olacaktır.3. Bellek optimizasyonu
Pandas kodunuzu daha “idiomatik” yapmanın üçüncü yolu —bu durumda “performant” olmaya daha yakın— bellek kullanımını optimize etmektir. Özellikle metot zincirleme kullanarak veri boru hatları oluşturmaya başladığınızda, belleğin hatlarınızın ne kadar hızlı çalıştığı üzerinde büyük bir etkisi olabileceğini göreceksiniz. Tüm bunları burada daha ayrıntılı göreceksiniz.
Bu küçük veri seti için biraz abartı olabilir; ancak bellek kullanımını optimize etmek adına bazı sütunları belirli tiplere dönüştürmek genellikle iyi bir pratiktir. Başlamak için,
ranking_dfiçin ne kadar bellek ayrıldığını.infometodu ile bulalım.Kodun ilk satırının sonucu bize verinin 144 KB yer kapladığını söylüyor. Ancak
.infometodunun argümanlarına bakıldığında, varsayılan olarak None olanmemory_usageadlı isteğe bağlı bir argüman olduğu görülür.memory_usageargümanınıdeepolarak ayarladığınızda ne olur?Yeni bellek ayak izi, ilk yanıtınızın 6 —daha doğrusu 5,6— katıdır.
Burada ne oldu?
Bellek tahminindeki fark, “deep” bayrağı açık değilken Pandas’ın
objectdtype’ı için bellek tüketimini tahmin etmemesinden kaynaklanır. Bu (Python) veri tipi, diğernumpytarafından optimize edilmişdtype’lardan daha fazla alan kaplar. Bu nedenleobjecttiplerini daha uygun tiplere dönüştürmek (örneğin kategorik verilerle çalışırkencategory) önerilir.Hadi yapalım!
Artık örneğin
world_rank’iint16’ya çevirmenin belleği daha verimli kullanacağını bildiğinize göre, bu değişiklikleri gerçekten uygulamanın zamanı geldi. Bunu yapmak içinastype()fonksiyonunu kullanabilirsiniz. Son olarak bellek kullanımınızın şimdi nasıl göründüğünü tekrar kontrol edin:Çok daha iyi.
yearsütununuint32’ye indirerek daha da optimize edebilirsiniz.4. GroupBy
Artık iyi biçimlendirilmiş bir veri kümesine sahip olduğumuza göre (yani düzenli durumda) ve bellek ayak izi optimize edildiğine göre veri analizi başlayabilir.
Cevaplamak isteyebileceğiniz bazı sorular var:
Hadi ilk soruyu, önceki bölümlerde gördüğünüz daha idiomatik Pandas ipuçlarını kullanarak ele alalım!
Başlamadan önce, ‘Massachusetts Institute of Technology (MIT)’ ve ‘Massachusetts Institute of Technology’ aynı üniversitenin iki farklı kaydıdır. Bu nedenle, ilk adı ikincisiyle değiştirin.
Bu gibi durumlarda, bu eğitimde daha önce gördüğünüz
locfonksiyonunun özellikle kullanışlı olduğunu unutmayın!Her bir sıralama sistemi için yıllar boyunca en iyi 5 (genel olarak
n) üniversiteyi bulmak için, işte sözde kodla nasıl yapılacağı:yearsütununda) ve her sıralama sistemi (namesütununda)) için:Uygulayalım.
Artık bu sıralama sözlüğü elimizdeyken, yıllar boyunca her iki sıralama yönteminin ne kadar (yüzde olarak) farklılaştığını bulalım: Seçilen ilk 5 üniversite aynıysa, sıralamaları aynı olmasa bile iki küme %100 benzer kabul edilir.
Gördüğünüz gibi bu zahmetliydi. Daha iyi, daha idiomatik bir Pandas yolu var mı?
Elbette var! Öncelikle, her yıl ve sıralama yöntemi için yalnızca en iyi 5 üniversiteyi tutacak şekilde sıralama DataFrame’ini filtreleyin. Sonucu
head()fonksiyonuyla da kontrol edin:Artık üzerinde çalışmak için doğru DataFrame elinizde olduğuna göre, yukarıda tanımlanan küme benzerliğini kullanarak her iki sıralama yöntemini karşılaştırmak için
.groupbymetodunu kullanalım.Yukarıdakiyle aynı sonuçları, daha az zahmetle elde edersiniz.
5. Görselleştirme
Veri setleriniz üzerinde bazı başlangıç analizlerinden geçtiğinize göre, verinizi görsel olarak da keşfetmenin zamanı geldi. Daha idiomatik Pandas kodu, Pandas’ın Matplotlib paketiyle çizim entegrasyonundan yararlanmanız anlamına da gelir. Bu sayede kısa sürede harika grafikler oluşturursunuz!
Bu bölüm için, Matplotlib ve Seaborn ile bazı temel görselleştirmeler yapmak üzere
times_dfveshanghai_dfveri setlerine geri döneceksiniz.Yukarıdaki grafik,
alumnisütunu için bazı 0 değerleri olduğunu anında gösterir. Verinizi keşfederken kesinlikle dikkate almanız gereken bir durumdur: veri profilleme yardımıyla bu 0 değerleri görebilir ve bunlarla başa çıkabilirsiniz. Bunun hakkında daha fazla bilgi edinmek isterseniz, DataCamp’in Veri Profilleme Eğitimine göz atın.Ya da veri setinizde yeri olmayan değerleriniz varsa, bunları basitçe
NaNile değiştirebilir ve ardından çizimi zorlaştıracak sütunlardaki tümNaNdeğerlerini kaldırabilirsiniz. Bunun, verinizi hızlıca ayarlamanın bir yolu olduğunu ve veri kalitenizi iyileştirmek için muhtemelen daha kapsamlı bir veri profilleme adımına ihtiyaç duyacağınızı unutmayın; çünkü aşağıdaki grafiktenum_studentssütunu için hâlâ 0 değerleri görüyorsunuz:Elbette verinizi görselleştirmek için kendinizi Matplotlib ile sınırlamak zorunda değilsiniz. Seaborn gibi verinizi hızlıca görselleştirmenizi sağlayan başka kütüphaneler de var.
Seaborn çizim aracı, esas olarak görsel olarak çekici istatistiksel grafikler oluşturmak için kullanılır (resmi sitede belirtildiği gibi). Aslında Matplotlib’in 2.0 sürümünden önce güzel grafikler oluşturmak zahmetliydi (yine de mümkündü).
Pandas ile Seaborn’un birleşimi, görselleştirmeler aracılığıyla veriniz üzerinde hızlıca yineleme yapmanıza da olanak tanır.
Hadi bazı örnekleri keşfedelim!
Aşağıdaki grafiğe bir göz atın: burada belirli bir ülkenin verinizde kaç kez göründüğünü sayıyorsunuz, ilk on gözlemi alıyorsunuz ve çubuk grafiğini çizerken sayımların en yüksekten en düşüğe sıralandığından emin oluyorsunuz:
Ardından bu ülkeleri ve ortalama puanlarını çizebilirsiniz:
Grafikleriniz oldukça karmaşık da olabilir. Aşağıdaki pairplot’a bakın; bir veri setindeki ikili ilişkileri daha net göstermek için tasarlanmıştır:
Benzer şekilde, en iyi 5 ülke için yıllar içinde
total_score’daki değişime dair içgörüler verenFacetGridveregplotbirleşimine göz atabilirsiniz:Son olarak, verinizi keşfederken bir korelasyon grafiği de işinize yarayabilir. Bunu yapmak için Seaborn’daki
heatmap()fonksiyonunu kullanabilirsiniz:Bu görselleştirmelerle daha da devam edebilirsiniz, bu yüzden belki de şimdilik durmak en iyisi :)
Sonraki Adımlar
Şimdilik bu kadar; Pandas ile çalışırken orta seviye teknikleri ve özellikle daha idiomatik Pandas kodu yazmayı öğrenmekten keyif aldığınızı umuyorum.
Bu blog yazısını beğendiyseniz ve Pandas’ta performans konusuna daha derinlemesine dalmak isterseniz, aşağıdaki ek materyalleri şiddetle öneririm: