Pandas Kütüphanesi — 2

Merhabalar. Serinin ilk konusunu okumadıysanız buradan okuyabilirsiniz.

4. Veri Gözlemleme ve Seçme (Viewing and Selecting Data)

  • .head() -- İlk 5 satırı gösterir

Şimdi veri setimize genel bir göz atalım.

# INPUTcar_sales = pd.read_csv(“car-sales.csv”)
df = car_sales.copy()
df
--------------------------------------------------------------------
# OUTPUT
car_sales

İlk 5 veriyi gözlemleyelim.

# INPUTdf.head()
--------------------------------------------------------------------
# OUTPUT
ilk 5 veri

Son 5 veriyi gözlemleyelim.

# INPUTdf.tail()
--------------------------------------------------------------------
# OUTPUT
son 5 veri

.head() ve .tail() ön tanımlı olarak 5 değerini almaktadır. Daha farklı sayıda gözlem için .head(7) -- ilk 7 gözlem, .tail(3) -- son 3 gözlem şeklinde kullanılabilir.

Gözlemlemeden sonra seçme işlemlerini de .loc[] ve .iloc[] kullanarak gerçekleştirebiliriz.

.loc[] index ismine dikkat ederek, .iloc[] ise index sıralamasına dikkat ederek seçme işlemini gerçekleştirir. Önce normal veri setimiz üzerinde, daha sonra ise kendi veri setimizi oluşturarak seçme işlemlerini gerçekleştirelim.

# INPUTdf.loc[0:3]
--------------------------------------------------------------------
# OUTPUT
# INPUTdf.iloc[0:3]
--------------------------------------------------------------------
# OUTPUT

.loc[] : tanımlandığı şekli ile seçim yapmak için kullanılır.
.iloc[] : alışık olduğumuz indeksleme mantığı ile seçim yapar.

Şimdi kendimiz bir veri seti oluşturup daha iyi anlayalım. Sıralamada indexleri normal aritmatik değil rastgele yerleştirelim.

# INPUThayvan = pd.Series([“kedi”, “kopek”, “kus”, “ayi”, “sincap”, “geyik”],
index=[0, 3, 9, 8, 67, 3])
hayvan
--------------------------------------------------------------------
# OUTPUT
0 kedi
3 kopek
9 kus
8 ayi
67 sincap
3 geyik
dtype: object
--------------------------------------------------------------------# INPUThayvan.index
--------------------------------------------------------------------
# OUTPUT
Int64Index([0, 3, 9, 8, 67, 3], dtype='int64')

.loc[]işlemine bakalım.

# INPUThayvan.loc[3]
--------------------------------------------------------------------
# OUTPUT
3 kopek
3 geyik
dtype: object

.iloc[]işlemine bakalım.

# INPUThayvan.iloc[3]
--------------------------------------------------------------------
# OUTPUT
'ayi'

Görüldüğü üzere .loc[] işleminde index ismine odaklanılırken, .iloc[] işleminde sıralamaya odaklanılıyor.

  • .loc[] -- index referans alırsak kullanılmalı

Bunlar dışında ismini bildiğimiz sütuna direk erişebilir ve işlemlerimizi gerçekleştirebiliriz.

# INPUTdf[‘Colour’]
--------------------------------------------------------------------
# OUTPUT
0 White
1 Red
2 Blue
3 Black
4 White
5 Green
6 Blue
7 Blue
8 White
9 White
Name: Colour, dtype: object

Dikkat: Bu yaptığımız işlem sonucunda Seri çıktısı alınıyor. Eğer DataFrame çıktısı almak istiyorsak aşağıdaki işlemi yapabiliriz.

# INPUTdf[[‘Colour’]]
--------------------------------------------------------------------
# OUTPUT
# INPUTdf[‘Price’]
--------------------------------------------------------------------
# OUTPUT
0 $4,000.00
1 $5,000.00
2 $7,000.00
3 $22,000.00
4 $3,500.00
5 $4,500.00
6 $7,500.00
7 $7,000.00
8 $6,250.00
9 $9,700.00
Name: Price, dtype: object

Koşullu işlemler ile seçme işlemi de yapabilriz.

İlk olarak Odometer (KM) > 100000 olan değerlere, daha sonra Make = Toyota olan verilere erişelim.

# INPUTdf[df[“Odometer (KM)”] > 100000]
--------------------------------------------------------------------
# OUTPUT
# INPUTdf[df["Make"] == "Toyota"]
--------------------------------------------------------------------
# OUTPUT

İstersek sadece belirli tiplerdeki verilere erişebilir ve gözlemleyebiliriz.

Sadece object tipindeki verileri ele alalım.

# INPUTdf_o = df.select_dtypes(include = [“object”])
df_o
--------------------------------------------------------------------
# OUTPUT

Renklerden kaçar tane olduğuna bakalım.

# INPUTdf_o[‘Colour’].value_counts()--------------------------------------------------------------------
# OUTPUT
White 4
Blue 3
Green 1
Black 1
Red 1
Name: Colour, dtype: int64

Bu şekilde işlemler yaparak çeşitli verilere ulaşabilir farklı sütunları karşılaştırabiliriz.

2 tane farklı sütunu göstermek ve karşılaştırmak için pd.crosstab() kullanabiliriz.

# INPUTpd.crosstab(df[“Make”], car_sales[“Price”])
--------------------------------------------------------------------
# OUTPUT

2'den fazla sütunu karşılaştırmak istediğimizde ise .groupby() kullanabiliriz.

# INPUTdf.groupby([“Make”]).mean()
--------------------------------------------------------------------
# OUTPUT
# INPUTdf.groupby(“Doors”).mean()
--------------------------------------------------------------------
# OUTPUT
# INPUTdf.groupby(‘Make’)[‘Doors’].mean()
--------------------------------------------------------------------
# OUTPUT
Make
BMW 5.00
Honda 4.00
Nissan 4.00
Toyota 3.75
Name: Doors, dtype: float64

Gruplama işlemi bu şekilde gerçekleştirilebilir ve aşağıdaki toplulaştırma işlemleri kullanılabilir.

  • count()

Ayrıca ileri topluluşatırma işlemleri de groupby ile rahatlıkla yapılabilir.

  • aggregate
# INPUTdf.groupby(“Make”).aggregate([min, np.median, max])
--------------------------------------------------------------------
# OUTPUT

.groupby() dışında daha iyi bir gruplama işlemi Pivot Tablolar ile yapılır. Pivot tabloları daha iyi anlayabilmek adına titanic veri setini kullanalım.

# INPUTimport seaborn as sns
titanic = sns.load_dataset(‘titanic’)
titanic.head()
--------------------------------------------------------------------
# OUTPUT

Şimdi cinsiyet ve hayatta kalma üzerine .groupby() kullanarak bir karşılaştırma gerçekleştirelim.

# INPUTtitanic.groupby(‘sex’)[[‘survived’]].mean()
--------------------------------------------------------------------
# OUTPUT

Görüldüğü üzere erkeklerde hayatta kalma oranı 0.18 iken kadınlarda bu oran 0.74.

Şimdi bu karşılaştırmaya kaldıkları yolcu sınıflarını da ekleyelim.

# INPUTtitanic.groupby(["sex","class"])[["survived"]].mean()
--------------------------------------------------------------------
# OUTPUT

Görüldüğü gibi daha ayrıntılı şekilde karşılaştırmalar gerçekleştirebiliriz. Bu işlemleri pivot tablo kullanarak gerçekleştirelim.

# INPUTtitanic.pivot_table(“survived”, index = “sex”, columns = “class”)
--------------------------------------------------------------------
# OUTPUT

Hem daha iyi bir görüntü oluştu hem de daha kolay yol ile tablo oluşturup analizimizi gerçekleştirdik.

Oluşturduğumuz verileri görselleştirmek her zaman işimizi kolaylaştıracaktır. Görselleştirme işlemi için matplotlib, seaborn gibi kütüphaneleri kullanabiliriz ya da basit bir şekilde pandas içerisinde .plot ve .hist ile görselleştirme yapabiliriz.

# INPUTdf[“Odometer (KM)”].plot();
--------------------------------------------------------------------
# OUTPUT

Dağılıma göz atalım

# INPUTdf["Odometer (KM)"].hist();
--------------------------------------------------------------------
# OUTPUT
# INPUTdf[‘Price’].plot();
--------------------------------------------------------------------
# OUTPUT
TypeError Traceback (most recent call last)
<ipython-input-108-c5dd96b02728> in <module>
----> 1 df['Price'].plot();

~/anaconda3/lib/python3.8/site-packages/pandas/plotting/_core.py in __call__(self, *args, **kwargs)
953 data.columns = label_name
954
--> 955 return plot_backend.plot(data, kind=kind, **kwargs)
956
957 __call__.__doc__ = __doc__

~/anaconda3/lib/python3.8/site-packages/pandas/plotting/_matplotlib/__init__.py in plot(data, kind, **kwargs)
59 kwargs["ax"] = getattr(ax, "left_ax", ax)
60 plot_obj = PLOT_CLASSES[kind](data, **kwargs)
---> 61 plot_obj.generate()
62 plot_obj.draw()
63 return plot_obj.result

~/anaconda3/lib/python3.8/site-packages/pandas/plotting/_matplotlib/core.py in generate(self)
276 def generate(self):
277 self._args_adjust()
--> 278 self._compute_plot_data()
279 self._setup_subplots()
280 self._make_plot()

~/anaconda3/lib/python3.8/site-packages/pandas/plotting/_matplotlib/core.py in _compute_plot_data(self)
439 # no non-numeric frames or series allowed
440 if is_empty:
--> 441 raise TypeError("no numeric data to plot")
442
443 self.data = numeric_data.apply(self._convert_to_ndarray)

TypeError: no numeric data to plot

Fiyatları görselleştirmeye çalıştığımızda, numerik değer sayılmadığı için hata aldık. .info() ile incelersek, verinin object olarak tanımlandığını görebiliriz. İleriki konularda nasıl dönüşüm yapabileceğimizden bahsedeceğiz.

# INPUTdf.info()
--------------------------------------------------------------------
# OUTPUT
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Make 10 non-null object
1 Colour 10 non-null object
2 Odometer (KM) 10 non-null int64
3 Doors 10 non-null int64
4 Price 10 non-null object
dtypes: int64(2), object(3)
memory usage: 528.0+ bytes

5. Veri Manipulasyonu (Manipulating Data)

Veri analizi, makine öğrenmesi ve derin öğrenme gibi konularda en çok yapılan işlemlerden biri veri manipülasyonudur. Yukarıda gördüğümüz gibi 'Price' aslında fiyat içeriyor ancak object olarak tanımlandığı için sayısal işlemleri gerçekleştiremiyoruz.

Veri manipülasyonunda çok fazla işlem vardır. Bu yüzden en çok kullanılanlara değinmeye çalışacağım. Öncelikle ‘Price’ değerlerini object’ten int64 değerlerine çevirelim ve manipülasyon işlemleri başlayalım.

Yukarıdaki sorunu internette aradığınızda Stackoverflow sitesinde bulacağınız çözüm bu şekildedir:
dataframe['amount'] = dataframe['amount'].str.replace('[\$\,\.]', '').astype(int)

# INPUTdf[“Price”] = df[“Price”].str.replace(‘[\$\,\.]’, ‘’).astype(int)

Şimdi veri tiplerini inceleyelim.

# INPUTdf.info()
--------------------------------------------------------------------
# OUTPUT
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Make 10 non-null object
1 Colour 10 non-null object
2 Odometer (KM) 10 non-null int64
3 Doors 10 non-null int64
4 Price 10 non-null int64
dtypes: int64(3), object(2)
memory usage: 528.0+ bytes

İnternetten bulduğumuz çözümü kendi verimize uygulayarak sorunumuzu çözmüş olduk. Şimdi görsel çizmeye kalkarsak veya diğer numerik işlemleri yapmaya kalkarsak herhangi bir sorun yaşamayız.

# INPUTdf.groupby('Make')['Price'].mean()
--------------------------------------------------------------------
# OUTPUT
Make
BMW 2200000
Honda 650000
Nissan 660000
Toyota 543750
Name: Price, dtype: int64

Şimdi isteğimize göre data manipülasyon işlemleri gerçekleştirelim.

Make sütununda tüm harfleri küçük harf yapalım.

# INPUTdf[‘Make’].str.lower()
--------------------------------------------------------------------
# OUTPUT
0 toyota
1 honda
2 toyota
3 bmw
4 nissan
5 toyota
6 honda
7 honda
8 toyota
9 nissan
Name: Make, dtype: object

Dikat: Yaptığımız işlemi orjinal veride kontrol edersek değişmediğini göreceğiz. Hemen alt tarafta değişiklik yaparak kaydedelim.

# INPUTdf[‘Make’] = df[‘Make’].str.lower()

Dikkat: Yapılan bu işlem sonunda orjinal veride değişiklike meydana geldi. Bu yüzden en başta işlemlere başlamadan önce .copy ile veri setinin kopyasını almıştık.

Orjinal Veri Seti = car_sales
Kopya = df

Verilerle işlemler yaparken en büyük sorunlardan birisi eksik veri olmasıdır. Eksik gözlemler ile ilgili en sık yapılan işlemler:

  • .isnull()

Şimdi eksik veri içeren yeni veri setimizi içe aktarıp veri manipülasyonuna devam edelim.

# INPUTcar_sales_missing = pd.read_csv("car-sales-missing-data.csv")
df_m = car_sales_missing.copy()
df_m
--------------------------------------------------------------------
# OUTPUT

Eksik gözlem var mı ?

# INPUTdf_m.isnull().values.any()
--------------------------------------------------------------------
# OUTPUT
True

Hangi sütunlarda ne kadar var ?

# INPUTdf_m.isnull().sum()
--------------------------------------------------------------------
# OUTPUT
Make 1
Colour 1
Odometer 4
Doors 1
Price 2
dtype: int64

Şimdi manipülasyon işlemi yapalım ve seçtiğimiz sütunda eksik değerleri ortalama ile dolduralım.

# INPUTdf_m['Doors'].fillna(df_m['Doors'].mean(), inplace = True)
df_m
--------------------------------------------------------------------
# OUTPUT

Şimdi tüm sütunlarda yer alan eksik değerleri silelim.

# INPUTdf_m.dropna(inplace = True)
df_m
--------------------------------------------------------------------
# OUTPUT

Dikkat: Silme işlemlerinde çok fazla seçenek vardır. Bunları konu sonunda vereceğim link sayesinde öğrenebilirsiniz. Konunun çok fazla uzamaması adına bunları geçiyorum.

Herhangi sütunlarda gerçekleştireceğimiz işlemle veya diğer sütunlarla alakası olmayan yeni sütunlar oluşturabiliriz.

İlk olarak object olan değeri int64 tipine dönüştürelim.

# INPUTdf_m["Price"] = df_m["Price"].str.replace('[\$\,\.]', '').astype(int)

Diğer sütunları kullanarak yeni bir sütun oluşturalım.

# INPUTdf_m["Price per KM"] = df_m["Price"] / df_m["Odometer"]
--------------------------------------------------------------------
# OUTPUT

Şimdi bağımsız bir sütun ekleyelim.

# INPUTdf_m["Number of wheels"] = 4--------------------------------------------------------------------
# OUTPUT

Herhangi bir sütunu kaldırma işlemi de gerçekleştirebiliriz.

# INPUTdf_m = df_m.drop("Price per KM", axis=1)
df_m
--------------------------------------------------------------------
# OUTPUT

Dikkat: Silme işlemi yaparken inplace = True kullanmamıza gerek yok. Bununla beraber axis=1 sütünları, axis=0 ise satırları temsil etmektedir.

Şimdi 0dometer verilerini km den mile çevirelim ve yeni bir sütun olarak kaydedelim.

# INPUTdf_m['Odometer (Miles)'] = df_m["Odometer"].apply(lambda x: x / 1.6)
df_m
--------------------------------------------------------------------
# OUTPUT

Pandas konusu çok geniş bir alandır ve yapılabilecekleri tek tek anlatmak pek mümkün değil. Bu seride en çok kullanılan işlemlere değinmeye çalıştım. Aşağıda vereceğim linkler sayesinde daha fazla bilgi edinebilirsiniz.

Co Founder of Türkiyerli