- Python Pandas Dersleri
- 1. Pandas Nedir?
- 2. Pandas Kütüphanesini Yükleme ve Çağırma
- 3. Veri Setini Tanıma, Veri Setinin İçeri Aktarılması ve İncelenmesi
- 4. Pandas Series ve Pandas DataFrame Kavramları
- 5. İndeksler
- 6. Filtreleme
- 7. Sütun ve Satır Güncelleme
- 8. Sütun ve Satır Ekleme ve Kaldırma
- 9. Sıralama
- 10. Gruplama ve Özetleme
- 10.1. Tekli Sütunun Bir İstatistik Değeri: median()
- 10.2. Çoklu Sütunların Bir İstatistik Değeri: median()
- 10.3. İstatistiksel Özet: describe()
- 10.4. Değerlerin Saydırılması: value_counts()
- 10.5. Değerlerin Yüzdelere Ayrılması: normalize
- 10.6. Gruplayarak Saydırma, Yüzde Alma ve İndeks İnceleme: groupby(), value_counts(), normalize ve loc
- 10.7. Bir Gruba Göre Bir İstatistik: groupby() ve median()
- 10.8. Bir Gruba Göre Birden Fazla İstatistik: groupby(), agg(), median() ve std()
- 10.9. Bir String İçeriğine Göre Bir İstatistik: groupby(), apply(), lambda, str.contains() ve sum()
- 11. Kayıp Veri
- 11.1. NaN Sayısını Öğrenme: isna() ve sum()
- 11.2. NaN ve Temizliği: dropna()
- 11.3. Kayıp Veriyi Anlatan Manuel Girilmiş String İfadeleri NaN Yapma: replace()
- 11.4. NaN Değerleri String Bir İfadeye Çevirme: fillna()
- 11.5. NaN Değerleri Bir Önceki Değere Çevirme: fillna()
- 11.6. NaN Değerleri Bir Sonraki Değere Çevirme: fillna()
- 11.7. NaN Değerleri Bir İstatistik Değerine Çevirme: fillna() ve mean()
- 11.8. NaN Değerlerinin Interpolasyon Tahmini: fillna() ve interpolate()
- 12. Verilerin Dışarı Aktarılması
Pandas, Python programlama dilinin üzerine inşa edilmiş hızlı, güçlü, esnek ve kullanımı kolay bir açık kaynak veri analizi ve manipülasyonu aracıdır.
Pandas'ı yüklemek için, Python paket yöneticisi olan pip
'i kullanabiliriz. Komut, aşağıdaki platformlarda çalıştırılabilir:
- Windows: Komut İstemi (Command Prompt, Cmd) veya PowerShell
- Linux: Terminal
- macOS: Terminal
Cmd kullanarak anlatacağım.
pip install pandas
Versiyon bilgisi yine Cmd'den aşağıdaki gibi öğrenilebilir.
python
import pandas as pd
pd.__version__
Bu dersin ilk paylaşımında 1.5.2
versiyonu kullanılıyor olacak.
Pandas başarıyla yüklendikten sonra aşağıdaki ifadeyi ekleyerek kütüphaneyi çağırabiliriz.
import pandas as pd
pd
kısaltmasını kullanmak yaygın bir uygulamadır ancak kısaltma isteğe bağlı olarak değiştirilebilir.
Ders anlatımında, İş Yatırım'ın Hisse Değerleri ve Oranları bölümünde bulunan Özet isimli tabloyu kullanacağız. Verilere buradan ulaşabilir ve excel olarak indirebilirsiniz. Veriye erişim tarihim 07/07/2023 olduğu için sizin verileriniz ile farklılıklar olabilir. Eğer GitHub hesabımdaki python-pandas-dersleri
repo'sunda bulunan data
'dan temelozet.xlsx
dosyasını indirirseniz herhangi bir farklılık olmayacaktır.
Veriyi aşağıdaki gibi içeri aktarabiliriz.
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx')
İlerleyen derslerde göreceğimiz DataFrame'in kısaltması olan df
'i kullanmak yaygın bir uygulamadır ancak değişken ismi isteğe bağlı olarak değiştirilebilir.
df.head()
df.head()
ile veri setinin ilk 5 satırına baktık. Burada 5 varsayılan değerdir. Örneğin, df.head(10)
ile ilk 10 satıra da bakılabilirdi.
df.tail()
df.tail()
ile veri setinin son 5 satırına baktık. Burada 5 varsayılan değerdir. Örneğin, df.tail(10)
ile son 10 satıra da bakılabilirdi.
Tam olarak satır ve sütun sayısı bilgisini alalım.
df.shape
df.shape
veri çerçevesinin boyutunu döndürür ve veri çerçevesinin satır ve sütun sayısını bir demet olarak verir. Örneğimizde, (509, 8) şeklinde bir çıktı veri çerçevesinin 509 satır ve 8 sütundan oluştuğunu gösterir.
(509, 8)
df.info()
fonksiyonu veri çerçevesi hakkında daha detaylı bilgiler sunar. Bu fonksiyon, veri çerçevesindeki her sütunun veri tipini, veri tiplerinin sayısal dağılımını, bellek kullanımını, eksik değerleri ve sütunların ve satırların toplamda kaç olduğu bilgisini gösterir.
df.info()
df.head()
veya df.tail()
ile çalıştırdığımızda sütunların eğer sütun sayısı fazla olsaydı sadece bir kısmını görebilirdik. Veri çerçevesindeki sütunların tamamını görmek isteseydik pd.set_option()
ile aşağıdaki ayarı yapabilirdik.
pd.set_option('display.max_columns', None)
None
kullanılmasının amacı, display.max_columns
seçeneğini sınırlamadan kaldırmaktır.
Aynı şekilde, satır sayısını da aşağıdaki gibi ayarlayabiliriz.
pd.set_option('display.max_rows', None)
None
kullanılmasının amacı, display.max_rows
seçeneğini sınırlamadan kaldırmaktır.
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx')
Pandas DataFrame (bizim örneğimizde içeri aktardığımız df
), iki boyutlu bir veri tablosunu temsil eder ve sütunlar ve satırlar şeklinde düzenlenmiş verileri içerir. Pandas Series ise (bizim örneğimizde içeri aktardığımız df
'in herhangi bir sütunu) tek boyutlu bir diziyi temsil eder ve sıralı bir şekilde indekslenmiş verileri içerir.
df_ornek = {
'Kod': ['A1CAP','ACSEL','ADEL','ADESE','AEFES','AFYON','AGESA'],
'Sektör': ['Aracı Kurumlar','Kimyasal Ürün','Kırtasiye','Perakande - Ticaret','Meşrubat / İçecek','Çimento','Sigorta']
}
Önce Pandas Series'e çevirelim.
pd_seri = pd.Series(df_ornek['Sektör'], index=df_ornek['Kod'])
pd_seri
Bu kod satırında, df_ornek
sözlüğünden Sektör
anahtarına karşılık gelen değerleri alarak bir Pandas Series oluşturduk. pd.Series()
işlevini kullanarak df_ornek['Sektör']
listesini ve df_ornek['Kod']
listesini sırasıyla values
ve index
parametreleri olarak verdik. index
, her bir veri noktasını tanımlayan etiketlerden oluşan bir dizidir.
Şimdi Pandas DataFrame'e çevirelim.
pd_df = pd.DataFrame(df_ornek)
pd_df
Veri çerçevesinde 0, 1, 2, ... gibi giden değerler görüyoruz. Bunlar indekstir ve indeksler her bir satırı tanımlayan tekil değerlerdir. Ancak tekil olmak zorunda değillerdir ki ilerleyen derslerde göreceğiz.
Son oluşturduğumuz veri çerçevesinden Sektör
sütununa erişmek istediğimizi varsayalım.
pd_df['Sektör']
Çıktı tanıdık geliyor. Hemen veri tipine bakalım.
type(pd_df['Sektör'])
Çıktının bir seriyi temsil eden pandas.core.series.Series
olduğunu göreceğiz. Serilerin tek boyutlu olduğunu öğrenmiştik. Veri çerçeveleri de serilerin birleşmesinden oluşuyor.
Aynı sütuna ulaşmanın bir başka yolu ise nokta notasyonunu kullanmaktır.
pd_df.Sektör
Yine aynı çıktıyı almış olacağız.
Hangi yöntemi tercih etmeliyiz?
pd_df['Sektör']
ifadesi, DataFrame üzerindeki sütuna doğrudan bir dizi indeksi kullanarak erişim sağlar. Bu yöntem, sütun ismi boşluk veya özel karakterler içerdiğinde veya Python programlama dilinde özel bir kelimeyle çakıştığında daha güvenlidir. Örneğin, eğer sütun ismi sutun ismi
veya if
gibi bir kelime ise bu ifadeleri kullanarak doğrudan sütuna erişim sağlayabiliriz.
pd_df.Sektör
ifadesi ise, nokta notasyonunu kullanarak sütuna erişim sağlar. Bu ifade daha kısa ve daha okunabilir bir yazım şekli sunar. Ancak bazı durumlarda, sütun ismi boşluk veya özel karakterler içeriyorsa veya Python programlama dilinde özel bir kelimeyle çakışıyorsa hata verebilir.
Daha önce oluşturduğumuz veri çerçevesine sütunlar ekleyip az önce öğrendiklerimizi pekiştirelim.
df_ornek = {
'Kod': ['A1CAP','ACSEL','ADEL','ADESE','AEFES','AFYON','AGESA'],
'Hisse Adı': ['A1 Capital', 'Acıselsan Acıpayam Selüloz', 'Adel Kalemcilik', 'Adese AVM', 'Anadolu Efes', 'Afyon Çimento', 'Agesa Hayat ve Emeklilik'],
'Sektör': ['Aracı Kurumlar','Kimyasal Ürün','Kırtasiye','Perakande - Ticaret','Meşrubat / İçecek','Çimento','Sigorta'],
'if': [False,False,False,False,True,True,False],
'@nerede': ['İstanbul','Denizli','İstanbul','Konya','İstanbul','İstanbul','İstanbul']
}
pd_df = pd.DataFrame(df_ornek)
Hisse Adı
sütununa erişmeye çalışalım.
pd_df['Hisse Adı']
Bir de nokta notasyonunu kullanalım.
pd_df.Hisse Adı
Yukarıdaki ifade ile ilgili sütuna erişmeye çalışırsak SyntaxError: invalid syntax
hatası alacağız.
Python programlama dilinde anahtar kelime (keyword) olan ve koşullu ifadeleri belirtmek için kullanılan if
isimli sütuna erişmeye çalışalım.
pd_df['if']
Yukarıdaki ifadeyi kullanırsak ilgili sütuna erişebileceğiz. Bir de nokta notasyonunu kullanalım.
pd_df.if
Yukarıdaki ifade ile ilgili sütuna erişmeye çalışırsak SyntaxError: invalid syntax
hatası alacağız.
Özel bir karakter olan @
'in kullanıldığı sütuna erişmeye çalışalım.
pd_df['@nerede']
Yukarıdaki ifadeyi kullanırsak ilgili sütuna erişebileceğiz. Bir de nokta notasyonunu kullanalım.
pd_df.@nerede
Yukarıdaki ifade ile ilgili sütuna erişmeye çalışırsak SyntaxError: invalid syntax
hatası alacağız.
Buraya kadar tek bir sütuna erişimi gördük. Birden fazla sütuna erişmek istediğimizde aşağıdaki ifadeyi kullanıyoruz.
pd_df[['Kod','Hisse Adı']]
Yukarıdaki iki duruma dikkat edelim. Birincisi, tek sütuna tek köşeli parantez ([]
) ile ulaşırken çoklu sütunlara çift köşeli parantez ([[]]
) ile ulaştık. İkincisi, tek sütuna erişirken çıktıyı bir seri olarak alıyorduk ancak çoklu sütunlara erişmek istediğimizde artık bir seri değil bir veri çerçevesi olarak çıktıyı alıyoruz.
Son olarak, sütun isimlerinin tamamını görmek istiyorsak aşağıdaki ifadeyi kullanabiliriz.
pd_df.columns
Yukarıdaki ifade ile Index(['Kod', 'Hisse Adı', 'Sektör', 'if', '@nerede'], dtype='object')
çıktısını almış olacağız.
Burada iki tane kavram ile tanışacağız: iloc
ve loc
.
iloc
, integer location anlamına gelir ve DataFrame veya Series üzerinde konum tabanlı indeksleme yapmamıza olanak tanır. İndeksler sıfırdan başlar ve satır veya sütunları belirlemek için tamsayı indekslerini kullanır. iloc
kullanırken satır veya sütunların konumunu belirtmek için köşeli parantez içinde tamsayı indeksleri kullanırız.
İlk satıra erişelim.
df.iloc[0]
Yukarıda indeksin sütun isimleri olduğunu görüyoruz.
Tek bir satıra erişebileceğimiz gibi birden fazla satıra da erişebiliriz. Tıpkı çoklu sütuna erişimde olduğu gibi ilerleyeceğiz.
df.iloc[[0,1]]
Görüldüğü üzere çift parantez kullandık ve çıktıyı bir veri çerçevesi olarak aldık.
iloc
ile sütunlara da erişebiliriz. Örneğin, ilk iki satırın 5. sütununa erişmeye çalışalım.
df.iloc[[0,1],4]
Piyasa Değeri(mn TL)
5. sütun olsa da indeksler sıfırdan başladığı için konumu 4'tür. Ayrıca çıktıyı seri olarak aldık.
Çoklu sütunlara da erişebiliriz. Örneğin, 4. ve 5. sütunlara erişelim.
df.iloc[[0,1],[3,4]]
Çoklu olduğu zaman veri çerçevesi olarak alıyoruz.
Son bir bilgi olarak, integer location'ları hangi sırayla yazarsak o sırayla çıktıyı alırız.
df.iloc[[1,0],[4,3]]
loc
, label location anlamına gelir ve DataFrame veya Series üzerinde etiket tabanlı indeksleme yapmak için kullanılan bir indeksleme yöntemidir.
İlk satıra erişelim. Burada 0 etiketine sahip satırı getireceğiz.
df.loc[0]
Tek bir satıra erişebileceğimiz gibi birden fazla satıra da erişebiliriz. Bu defa örnek olarak 0 ve 1 etiketlerine sahip satırları getireceğiz.
df.loc[[0,1]]
Buraya kadar yaptıklarımız aslında iloc
'ta yaptıklarımıza benziyor ancak biz etiket bazlı ilerliyoruz. Son olarak, son sütuna erişelim.
df.loc[[0,1], 'Sermaye(mn TL)']
iloc
'tan farklı olarak sütuna erişmek istediğimizde direkt olarak ismini yazdık.
Çoklu sütunlara da erişebiliriz. Örneğin, aşağıdaki iki sütuna erişelim.
df.loc[[0,1], ['Piyasa Değeri(mn TL)','Piyasa Değeri(mn $)']]
Yine sütun isimlerini belirttik ve çift parantez kullandık. Aynı zamanda çoklu olduğu için veri çerçevesi olarak aldık.
Son bir bilgi olarak, label location'ları hangi sırayla yazarsak o sırayla çıktıyı alırız.
df.loc[[1,0], ['Piyasa Değeri(mn $)','Piyasa Değeri(mn TL)']]
Örneğin, ilk 5 hissenin kod bilgilerine erişmek istediğimizi varsayalım. Bu durumda indeks veya etiketleri tek tek yazmamıza gerek kalmayacak. :
kullanarak da ilk 5 satıra erişebiliriz. Burada dikkat etmemiz gereken nokta çift parantez yerine tek parantez kullanacak olmamızdır.
df.iloc[0:4,0]
# veya
df.loc[0:4, 'Kod']
Aynısını :
kullanarak sütunlar için de yapabiliriz. Kod
sütunundan sonra gelen Hisse Adı
, Sektör
ve Kapanış(TL)
sütunlarını da almak istediğimizi varsayalım.
df.iloc[0:4, 0:4]
# veya
df.loc[0:4, 'Kod':'Kapanış(TL)']
Sektörlere ve bunlara ait sayılara ulaşalım.
df['Sektör'].value_counts()
Görüldüğü üzere, GYO
sektörünün sayısı 41 ile ilk sırada yer alıyor. En az şirkete sahip sektörler 1 ile Eğlence Hizmetleri
ve Cam
olmuş.
Visual Studio Code editörünü kullananlar için: Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...
şeklinde bir bilgilendirme alabilirsiniz. Burada, scrollable element
veya text editor
seçeneklerine tıklarsanız çıktının tamamını görebilirsiniz.
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx')
df
Sol tarafta bir sütunmuş gibi görünen 0, 1, 2, ... değerleri indekstir. İndeksler, bir numaralandırma veya etiketleme mekanizmasıdır. Örneğin, bir liste içindeki elemanların her biri bir indeks değerine sahiptir ve bu indeksler kullanılarak elemanlara erişebiliriz. Örneğimizdeki veri çerçevesinde indeks, satırları etiketlemek veya numaralandırmak için kullanılır. Varsayılan olarak, veri çerçevesinin indeksi sıfırdan başlayan tam sayılarla oluşturulur. Bununla birlikte, indeksler benzersiz olmak zorunda değildir. Yani aynı indeks değeri birden fazla satıra karşılık gelebilir.
İndeks ayarlamayı iki şekilde yapabiliriz. Birincisi, set_index()
fonksiyonunu kullanmaktır.
Örneğimizdeki Kod
sütununu indeks olarak ayarlamak istediğimizi varsayalım.
df = df.set_index('Kod')
df
Yukarıda Kod
sütununu indeks olarak ayarladık. Ancak değişiklikleri yine aynı veri çerçevesine atadık. Bunu yapmak yerine inplace
parametresini True
olarak ayarlayabiliriz.
df.set_index('Kod', inplace=True)
df
İkincisi ise veriyi içeri aktarma sırasında index_col
ile indeks ayarlaması yapmaktır.
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
df
İndeksin ne olduğunu aşağıdaki gibi kontrol edebiliriz. name
ile indeksin Kod
olarak ayarlandığını görebiliriz.
df.index
loc
ile THYAO
indeksine ulaşalım. Aslında burada iloc
ile loc
'un ayrımı daha net görmüş olacağız.
df.loc['THYAO']
Aynı indeksin Halka AçıklıkOranı (%)
değerine bakalım.
df.loc['THYAO', 'Halka AçıklıkOranı (%)']
Çıktıyı 50.4
olarak alacağız.
Yeri gelmişken, iloc
ile loc
'un farkını aşağıdaki gibi gösterebiliriz.
df.iloc[0]
Yukarıda iloc A1 Capital
indeksinin değerlerini sağlıklı bir şekilde verebilirken loc
'u aynı şekilde kullandığımızda KeyError
hatası alacağız.
df.loc[0]
İndeksi Kod
olarak ayarlamıştık. Varsayılan indeks değerlerine aşağıdaki gibi dönebiliriz.
df.reset_index(inplace=True)
df
İndeksleri artan sırada olacak şekilde sıralayabiliriz.
df.sort_index()
Eğer sıralamayı azalan sırada yapmak istersek ascending
parametresini False
yapmamız gerekiyor.
df.sort_index(ascending=False)
Eğer sıralamanın kalıcı olmasını istersek inplace
parametresini True
yapmalıyız.
df.sort_index(ascending=False, inplace=True)
# ya da
df.sort_index(inplace=True)
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
Sektör
sütununun Bankacılık
olduğu değerleri filtreleyelim.
Filtrelemenin birden fazla yolu olabilir.
İlki olan iç içe yöntemine bakalım.
df[df['Sektör'] == 'Bankacılık']
İkinci bir yol olarak loc
'u kullanabiliriz. Hatta burada filtrelemenin yanında herhangi bir sütunu da seçebiliriz. Örneğin, Halka AçıklıkOranı (%)
sütununu alalım.
df.loc[df['Sektör'] == 'Bankacılık', 'Halka AçıklıkOranı (%)']
Birden fazla filtreleme yapmak istediğimizde mantıksal operatörleri kullanabiliriz.
Örneğin, hem Sektör
sütunundan Bankacılık
değerini hem de Halka AçıklıkOranı (%)
sütunundan 50'den büyük olanları alalım ve Hisse Adı
sütunundaki değerleri getirelim.
df.loc[(df['Sektör'] == 'Bankacılık') & (df['Halka AçıklıkOranı (%)'] > 50), 'Hisse Adı']
Burada, her bir filtreleme işlemini parantez içerisine aldık. Örnekte, ve anlamına gelen &
operatörünü kullandık. Bir de veya anlamına gelen |
operatörünü kullanalım.
df.loc[(df['Sektör'] == 'Bankacılık') | (df['Halka AçıklıkOranı (%)'] > 50), 'Hisse Adı']
Ve anlamına gelen &
kullandığımız örneğe uymayan (tersi) değerleri getirelim. Bunun için ~
kullanmamız yeterli olacaktır. Yani, Sektör
sütunu Bankacılık
dışı olan ve Halka AçıklıkOranı (%)
sütunu <=50 olacak ve Hisse Adı
değerleri gelecek.
df.loc[~(df['Sektör'] == 'Bankacılık') & ~(df['Halka AçıklıkOranı (%)'] > 50), 'Hisse Adı']
Eğer yukarıdaki ifadeyi ~
her iki filtreyi de dışarıdan kapsayacak şekilde yazarsak Sektör
sütunu Bankacılık
olan ve Halka AçıklıkOranı (%)
sütunu >50 olanları ilk başta alıp sonra bunun dışında kalanları alacak ve Hisse Adı
değerlerini getirecek. İlk koşula uyan bir tek AKBNK var. Bunun dışında kalan da 508 hisse olacak.
df.loc[~((df['Sektör'] == 'Bankacılık') & (df['Halka AçıklıkOranı (%)'] > 50)), 'Hisse Adı']
Alternatif bir yol olarak isin()
kullanılabilir.
df_sektor = df.loc[df['Sektör'].isin(['GYO','Bankacılık'])]
df_sektor
Sadece Hisse Adı
sütununu alalım.
df_sektor = df.loc[df['Sektör'].isin(['GYO','Bankacılık']), 'Hisse Adı']
df_sektor
Yukarıda yapılan işlemin karışık gelmemesi için parçalara ayırabiliriz. Böylece yaptığımız işlem daha net anlaşılabilir.
sektorler = ['GYO','Bankacılık']
sektorler_filtre = df['Sektör'].isin(sektorler)
df_sektor = df.loc[sektorler_filtre, 'Sektör']
df_sektor
Hisse Adı
sadece Enerji
içerenleri filtreleyelim. Bunun için bir string'i içerip içermediği kontrolü yapmış olacağız.
df_filtre_enerji = df.loc[df['Hisse Adı'].str.contains('Enerji', na=False)]
df_filtre_enerji
İhtiyacımız olmamasına rağmen na
parametresini False
olacak şekilde ekledik. İlgili sütunda NA / NaN
içerdiğini varsayalım. Bu durumda kodu çalıştırdığımızda ValueError: Cannot mask with non-boolean array containing NA / NaN values
hatası alırdık. na=False
olarak ayarlandığında, contains()
fonksiyonu eksik değerleri içeren satırları dikkate almadan sadece Enerji
kelimesini içeren satırları filtrelemek için kullanılır. Yani, Hisse Adı
sütununda Enerji
kelimesini içeren satırları seçerken eksik değerleri göz ardı eder.
Sadece ilgilendiğimiz Hisse Adı
sütununu alalım.
df_filtre_enerji = df.loc[df['Hisse Adı'].str.contains('Enerji', na=False), 'Hisse Adı']
df_filtre_enerji
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
Tüm sütunların isimlerini güncelleyelim.
df.columns = [
'HisseAdi',
'Sektor',
'KapanisTL',
'PiyasaDegeriMnTL',
'PiyasaDegeriMnUSD',
'HalkaAciklikOraniYuzde',
'SermayeMnTL'
]
df
Tüm sütun isimlerini büyük harfe çevirelim. Bu işlemi tek tek yapmak yerine list comprehension yöntemi ile yapacağız.
df.columns = [sutun.upper() for sutun in df.columns]
df
Bu kod, bir Pandas DataFrame'in sütun isimlerini büyük harflere dönüştürmek için kullanılan bir dizi ifadedir. Kod, list comprehension yöntemini kullanarak, DataFrame'in sütunlarını tek tek dolaşarak her bir sütunun ismini büyük harflere dönüştürür ve bu dönüşüm sonucunda oluşan yeni sütun isimlerini DataFrame'in sütunlarına atar.
USD içeren sütunları $
ile değiştirelim.
df.columns = df.columns.str.replace('USD','$')
df
Hepsini tekrar list comprehension ile bu defa küçük yapalım.
df.columns = [sutun.lower() for sutun in df.columns]
df
Sütun güncellemeyi rename()
ile de yapabiliriz. Değişikliklerin uygulanması için inplace
parametresini de True
yapalım.
df.rename(columns={
'hisseadi':'HisseAdi',
'sektor':'Sektor',
'kapanistl':'KapanisTL',
'piyasadegerimntl':'PiyasaDegeriMnTL',
'piyasadegerimn$':'PiyasaDegeriMnUSD',
'halkaaciklikoraniyuzde':'HalkaAciklikOraniYuzde',
'sermayemntl':'SermayeMnTL'
}, inplace=True)
df
A1CAP
etiketine sahip satırdaki bilgileri güncelleyelim.
df.loc['A1CAP'] = ['A1 Capital (Test)','Aracı Kurumlar (Test)',26.80,3618.0,138.7,25.9,135]
df
Burada ilgili satırdaki bazı sütunlara denk gelen değerleri güncelledik. Eğer çok daha fazla sütun olsaydı tek tek hepsini yazmak zor olurdu. Bilgisini değiştirdiğimiz Hisse Adı
ve Sektör
sütunlarına ait değerleri eski haline getirelim.
df.loc['A1CAP', ['Hisse Adı','Sektör']] = ['A1 Capital','Aracı Kurumlar']
df
Eğer tek bir değeri güncellemek istersek bunu iki farklı yoldan yapabiliriz. Birincisi, her zaman kullandığımız loc
; ikincisi ise at
yöntemi.
df.loc['A1CAP', 'Hisse Adı'] = 'A1 Capital Test'
# veya
df.at['A1CAP', 'Hisse Adı'] = 'A1 Capital Test'
df
Bir filtreleme sonrası da tek bir hücre için güncelleme yapılabilir.
df.loc[df['Sektör'] == 'Bankacılık', 'Halka AçıklıkOranı (%)'] = 0
df.loc[df['Sektör'] == 'Bankacılık', 'Halka AçıklıkOranı (%)']
Çoklu satır güncellemesi yapmak istediğimiz zaman birkaç farklı yolu kullanabiliriz. Örneğin, Hisse Adı
sütunundaki tüm değerleri küçük yapalım. Bunun için birincisi str.lower()
kullanabiliriz.
df['Hisse Adı'] = df['Hisse Adı'].str.lower()
df
İkinci bir yol olan apply()
ile Hisse Adı
sütunundaki tüm değerleri büyük harfli yapalım. Bunun için önce bir fonksiyon yazıp ardından bu fonksiyonu apply()
ile uygulayacağız.
def hisse_adi_guncelle(hisse_adi):
return hisse_adi.upper()
df['Hisse Adı'] = df['Hisse Adı'].apply(hisse_adi_guncelle)
df
Üçüncü bir yol olan apply()
ve lambda
ile Hisse Adı
sütunundaki tüm değerlerin yalnızca ilk harflerini büyük bırakalım.
df['Hisse Adı'] = df['Hisse Adı'].apply(lambda x: x.capitalize())
# veya
df['Hisse Adı'] = df['Hisse Adı'].apply(lambda x: x.title())
# veya
df['Hisse Adı'] = df['Hisse Adı'].apply(lambda x: x[0] + x[1:].lower())
df
Dördüncü bir yol olan applymap()
ve lambda
ile Hisse Adı
ve Sektör
sütunlarındaki harfleri küçük yapalım.
df[['Hisse Adı','Sektör']] = df[['Hisse Adı','Sektör']].applymap(lambda x: x.lower())
df
Beşinci bir yol olan map()
veya replace()
ile seriler üzerinde güncelleme işlemleri yapabiliriz.
df['Hisse Adı'].map({'a1 capital test':'a1 capital'})
Ancak map()
yönteminde eşleştirme sözlüğünde yer almayan değerler dönüşüm sırasında NaN
olarak kabul edilir. Bu noktada replace()
fonksiyonunu kullanabiliriz.
df['Hisse Adı'].replace({'a1 capital test':'a1 capital'})
Değişiklikleri kaydetmek için yine aynı veri çerçevesine atayabiliriz.
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
Hisse Adı
sütunu ile Sektör
sütununu yeni bir sütunda birleştirelim.
df['HisseAdi@Sektor'] = df['Hisse Adı'] + '@' + df['Sektör']
df
Hisse Adı
ve Sektör
sütunlarına ihtiyacımız olmadığını düşünelim. Bunları drop()
yardımıyla kaldırabiliriz. Değişiklikleri de aynı veri çerçevesine inplace
parametresini True
yapıp kaydedelim.
df.drop(columns=['Hisse Adı','Sektör'], inplace=True)
df
Kaldırdığımız sütunları tekrar yerine koyalım. Bunun için str.split()
fonksiyonunu kullanacağız.
df['HisseAdi@Sektor'].str.split('@')
Sonucu yeni sütunlar olarak genişletelim. Bunu, expand
parametresi ile yapacağız.
df['HisseAdi@Sektor'].str.split('@', expand=True)
Yeni oluşan sütunları veri çerçevesine ekleyelim.
df[['Hisse Adı','Sektör']] = df['HisseAdi@Sektor'].str.split('@', expand=True)
df
Sadece Hisse Adı
sütununa bir veri girişi yapalım. Bunu append()
ile yapacağız.
df.append({'Hisse Adı':'TEST'})
Eğer bu şekilde yaparsak TypeError: Can only append a dict if ignore_index=True
hatasını alacağız. Bu hata, yalnızca bir sözlüğü veri çerçevesine ekleyebileceğimizi söylüyor. Bunu ignore_index
parametresini True
yaparak aşabiliriz.
df.append({'Hisse Adı':'TEST'}, ignore_index=True)
Görüldüğü üzere, diğerlerini NaN
olarak ekledi.
İki veri çerçevesini birleştirelim. Bunun için bir veri çerçevesi daha oluşturalım. İlk veri çerçevesini de ilk hali ile kullanalım.
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
df2 = {
'Kod':['TST'],
'Hisse Adı':['TEST'],
'Sektör':['Bankacılık'],
'Kapanış(TL)':[0],
'Piyasa Değeri(mn TL)':[0],
'Piyasa Değeri(mn $)':[0],
'Halka AçıklıkOranı (%)':[0],
'Sermaye(mn TL)':[0],
'USDTRY':26
}
df2 = pd.DataFrame(df2)
df2.set_index('Kod', inplace=True)
df2
İkinci veri çerçevesinde bir sütun fazla. Bu durumda birleştirme sırasında bunu görmezden geleceğiz.
df3 = df.append(df2, ignore_index=True)
df3
Burada aslında çıkan uyarıları da dikkate almamız gerekiyor. Son kodu çalıştırdığımızda bize FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.
şeklinde bir uyarı veriliyor. Bu uyarı, append()
fonksiyonunun pandas'ın gelecekteki bir sürümünde kullanımdan kaldırılacağını ve bunun yerine concat()
fonksiyonunu kullanmamız gerektiğini söylüyor. Biz de kullanalım.
df3 = pd.concat([df,df2], ignore_index=True)
df3
Yine aynı çıktıyı aldık.
509 numaralı indeksi kaldırmak istediğimizi varsayalım. Daha önce kullandığımız drop()
fonksiyonunun içine index
parametresini ekleyerek kaldırma işlemini gerçekleştirebiliriz.
df3.drop(index=509, inplace=True)
df3
Yukarıda sadece bir adet indeks belirtip onu kaldırdık. Sadece Aracı Kurumlar
içeren satırları indeks ile kaldırmak istediğimizi varsayalım. Önce koşulu belirteceğiz ardından da bu koşulun indekslerini alacağız.
df3.drop(index=df3[df3['Sektör'] == 'Aracı Kurumlar'].index, inplace=True)
df3
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
Veri çerçevesini kapanış fiyatlarına göre sıralayalım.
df.sort_values(by='Piyasa Değeri(mn $)', inplace=True)
df
Yukarıda küçükten büyüğe doğru sıraladık. Şimdi ise büyükten küçüğe doğru sıralayalım.
df.sort_values(by='Piyasa Değeri(mn $)', ascending=False, inplace=True)
df
Sektör
sütununa göre artan ve Piyasa Değeri(mn $)
sütununa göre azalan şekilde sıralayalım.
df.sort_values(by=['Sektör','Piyasa Değeri(mn $)'], ascending=[True, False], inplace=True)
df
İndekse göre artan bir şekilde sıralayabiliriz.
df.sort_index(inplace=True)
df
İndekse göre azalan bir şekilde de sıralayabiliriz.
df.sort_index(ascending=False, inplace=True)
df
Sektör
sütununu alıp seri olacak şekilde bir sıralama yapabiliriz.
df['Sektör'].sort_values()
Piyasa Değeri(mn $)
sütununa göre piyasa değeri $ cinsinden en yüksek 10'a bakalım.
df.nlargest(10, 'Piyasa Değeri(mn $)')
Piyasa Değeri(mn $)
sütununa göre piyasa değeri $ cinsinden en düşük 10'a bakalım.
df.nsmallest(10, 'Piyasa Değeri(mn $)')
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
Piyasa Değeri(mn $)
sütununun medyan değerine bakalım.
df['Piyasa Değeri(mn $)'].median()
Piyasa değerinin 107.3
milyon $ olduğu öğrendik.
Piyasa Değeri(mn TL)
ve Piyasa Değeri(mn $)
sütunlarının medyan değerine bakalım.
df[['Piyasa Değeri(mn TL)','Piyasa Değeri(mn $)']].median()
Sayısal veri tipine sahip sütunların istatistiksel özetlerine bakalım.
İstatistiksel özet:
- count: Sütundaki non-null (boş olmayan) değerlerin sayısı.
- mean: Sütundaki değerlerin ortalaması.
- std: Sütundaki değerlerin standart sapması.
- min: Sütundaki en küçük değer.
- 25%: Alt çeyrek yüzdesi, sütundaki değerlerin %25'inin altında olan değer.
- 50%: Medyan veya ortanca, sütundaki değerlerin yarısından küçük ve yarısından büyük olan değer.
- 75%: Üst çeyrek yüzdesi, sütundaki değerlerin %75'inin altında olan değer.
- max: Sütundaki en büyük değer.
df_istatistiksel_ozet = df.drop(['Hisse Adı','Sektör'], axis=1)
df_istatistiksel_ozet.describe()
axis=0
'da (varsayılan değer) işlemler satırlar boyunca yapılır. axis=1
'de ise işlemler sütunlar boyunca yapılır.
Sektör
sütunundaki değerleri saydıralım.
df['Sektör'].value_counts()
Sektör
sütunundaki değerleri saydırmıştık. Bunların yüzde paylarını normalize
parametresini True
yaparak alabiliriz.
df['Sektör'].value_counts(normalize=True)
10.6. Gruplayarak Saydırma, Yüzde Alma ve İndeks İnceleme: groupby(), value_counts(), normalize ve loc
Öncelikle Halka AçıklıkOranı (%)
sütununa göre yeni bir sütun oluşturalım. 50'den büyüksek >50
; küçük veya eşitse <=50
yazsın.
df['HalkaAciklikOraniGrup'] = df['Halka AçıklıkOranı (%)'].apply(lambda x: '>50' if x > 50 else '<=50')
df
Şimdi Sektör
sütununa göre HalkaAciklikOraniGrup
sütununu saydıralım.
df.groupby(['Sektör'])['HalkaAciklikOraniGrup'].value_counts()
İstediğimizi elde ettik. Son olarak örneğin, Teknoloji
sektörüne bakalım.
df.groupby(['Sektör'])['HalkaAciklikOraniGrup'].value_counts().loc['Teknoloji']
Görüldüğü üzere, ilgilendiğimiz sektördeki halka açıklık dağılımı bilgisine gruplandırılmış olarak ulaştık. Aynı bilgiye yüzde olarak da erişebiliriz.
df.groupby(['Sektör'])['HalkaAciklikOraniGrup'].value_counts(normalize=True).loc['Teknoloji']
Sektör
sütununa göre sektörlerin piyasa değerlerinin medyanını Piyasa Değeri(mn $)
sütununu kullanarak alalım.
df.groupby(['Sektör'])['Piyasa Değeri(mn $)'].median()
Sektör
sütununa göre sektörlerin piyasa değerlerinin medyanını Piyasa Değeri(mn $)
sütununu kullanarak alalım. Bunun yanına bir de standart sapma ekleyelim.
df.groupby(['Sektör'])['Piyasa Değeri(mn $)'].agg(['median','std'])
Sütun isimlerini güncelleyebiliriz.
df.groupby(['Sektör'])['Piyasa Değeri(mn $)'].agg(Medyan='median',StandartSapma='std')
Hisse Adı
sütununda Enerji
içeren hisseleri HalkaAciklikOraniGrup
sütununa göre saydıralım.
df.groupby(['HalkaAciklikOraniGrup']).apply(lambda x: x['Hisse Adı'].str.contains('Enerji').sum())
# veya
df.groupby(['HalkaAciklikOraniGrup'])['Hisse Adı'].apply(lambda x: x.str.contains('Enerji').sum())
import pandas as pd
df = pd.read_excel('./data/temelozet.xlsx', index_col='Kod')
Bazı sütunların bazı değerlerini NaN
yapalım.
import numpy as np
np.random.seed(34)
random_satirlar = df.sample(n=200)
df2 = df
df2.loc[random_satirlar.index, ['Kapanış(TL)','Piyasa Değeri(mn $)']] = np.nan
df2
Her bir sütunda kaç adet NaN
olduğunu bulabiliriz.
df2.isna().sum()
Eğer yukarıda bir sum()
daha eklersek toplam NaN
sayısını alırız.
df2.isna().sum().sum()
Bu da 400
değerini verecektir.
dropna()
kullanarak NaN
içeren satırları kaldırabiliriz.
df2.dropna()
509 satırlık veri çerçevesinin iki sütununa 200 adet NaN
atamıştık. 200'ünü de kaldırıp 309 satırlık bir veri çerçevesi bıraktı.
dropna()
'i aşağıdaki gibi özelleştirerek de kullanabilirdik.
df2.dropna(axis='index', how='all', subset=['Kapanış(TL)','Piyasa Değeri(mn $)'])
Eksik değerlerin satırlarda bulunduğunu belirtmek için axis='index'
parametresi kullanılır. how='all'
parametresi, bir satır veya sütunda tüm değerlerin eksik olduğu durumu belirtir. 'all'
değeri, tüm değerlerin eksik olduğu satırları çıkarmak için kullanılır. Yani, bir satırdaki tüm belirtilen sütunlarda eksik değer varsa o satır veri çerçevesinden çıkarılır. subset
parametresi ile eksik değerlerin kontrol edileceği sütunları belirttik. Sonuç olarak, Kapanış(TL)
ve Piyasa Değeri(mn $)
sütunlarında eksik değerleri olan satırları veri çerçevesinden çıkardık.
Bazı sütunların bazı değerlerini NaN
yapmak yerine Veri Yok
yazdığımızı varsayalım.
import numpy as np
np.random.seed(34)
random_satirlar = df.sample(n=200)
df2 = df
df2.loc[random_satirlar.index, ['Kapanış(TL)','Piyasa Değeri(mn $)']] = 'Veri Yok'
df2
Veri Yok
yazan satırları replace()
ile NaN
yapalım.
df2.replace(to_replace='Veri Yok', value=np.nan, inplace=True)
df2
NaN
içeren satırları belirlediğimiz bir string ifadeye çevirelim.
df2.fillna(value='VERI YOK')
import numpy as np
np.random.seed(34)
random_satirlar = df.sample(n=200)
df2 = df
df2.loc[random_satirlar.index, ['Kapanış(TL)','Piyasa Değeri(mn $)']] = np.nan
Bu örnek için pek anlamlı olmasa da nasıl yapıldığını görmek için yapmış olalım. Bunun için method
parametresini pad
yapacağız.
df2.fillna(method = 'pad')
import numpy as np
np.random.seed(34)
random_satirlar = df.sample(n=200)
df2 = df
df2.loc[random_satirlar.index, ['Kapanış(TL)','Piyasa Değeri(mn $)']] = np.nan
Bu örnek için pek anlamlı olmasa da nasıl yapıldığını görmek için yapmış olalım. Bunun için method
parametresini bfill
yapacağız.
df2.fillna(method = 'bfill')
import numpy as np
np.random.seed(34)
random_satirlar = df.sample(n=200)
df2 = df
df2.loc[random_satirlar.index, ['Kapanış(TL)','Piyasa Değeri(mn $)']] = np.nan
Bu örnek için pek anlamlı olmasa da nasıl yapıldığını görmek için yapmış olalım. İstatistik olarak ortalamayı kullanalım.
df2.fillna(value=df2['Kapanış(TL)'].mean())
import numpy as np
np.random.seed(34)
random_satirlar = df.sample(n=200)
df2 = df
df2.loc[random_satirlar.index, ['Kapanış(TL)','Piyasa Değeri(mn $)']] = np.nan
Bu örnek için pek anlamlı olmasa da nasıl yapıldığını görmek için yapmış olalım. method
parametresini linear
yapacağız.
df2.interpolate(method='linear')
# En basit haliyle kaydetme
df.to_csv('./data/temelozet_v2.csv')
# İndeksleri çıkarma
df.to_csv('./data/temelozet_v2.csv', index=False)
# Türkçe karakterleri dikkate alma
df.to_csv('./data/temelozet_v2.csv', index=False, encoding='utf-8')
# Zip'li kaydetme
zip_secenekler = dict(method='zip', archive_name='output.csv')
df.to_csv('./data/output.zip', compression=zip_secenekler)
# Farklı bir dosyaya kaydetme (yol-1)
from pathlib import Path
dosya_yolu = Path('./data/data_alt/temelozet_v2.csv')
dosya_yolu.parent.mkdir(parents=True, exist_ok=True)
df.to_csv(dosya_yolu)
# Farklı bir dosyaya kaydetme (yol-2)
import os
os.makedirs('./data/data_alt', exist_ok=True)
df.to_csv('./data/data_alt/temelozet_v2.csv')
# En basit haliyle kaydetme
df.to_excel('./data/temelozet_v2.xlsx')
# İndeksleri çıkarma
df.to_excel('./data/temelozet_v2.xlsx', index=False)
# Sheet ismini değiştirme
df.to_excel('./data/temelozet_v2.xlsx', sheet_name='IsYatirim')