800100715151 Astronomide Veritabanları

Ders - 02 Pandas Paketi'ne Giriş

Doç. Dr. Özgür Baştürk
Ankara Üniversitesi, Astronomi ve Uzay Bilimleri Bölümü
obasturk at ankara.edu.tr
http://ozgur.astrotux.org

pandas Modülü

pandas Python programlama dili için yazılmış, BSD-lisanslı açık kaynak kodlu, yüksek performanslı, kolay kullanılabilen veri yapıları ve analiz araçları sağlayan bir kütüphanedir (pandas dokümantasyonu). Üzerine kurulu olduğu, bir yaygın sayfa yapısına benzer, sütunların isimlendirildiği veri çerçevesi nesnesi (ing. DataFrame) sayesinde veriyle kolay ve hızlı etkileşim sağlar.

series Nesnesi

Seriler (series) etiketlendirlmiş birer bir boyutlu (1D) dizidir. Yapısı sözlük (dictionary) yapısına benzer, tıpkı numpy dizileri gibi sabit bir uzunluğa sahiptir. Değer almayan ya da 'N/A', 'NaN', '-' gibi nümerik olmayan değerler alan sütunların yönetimine de olanak sağlar. Numpy ya da Python'un satandart işlem ya da fonksiyonlarının üzerinde kullanılabildiği bir yapıdır. Örneğin sözlüklerde (dictionary) bu işlem ve fonksiyonların çok büyük bir bölümü kullanılamaz. pandas modülünün üzerine kurulu olduğu DataFrame yapısının temelinde pandas serileri vardır. pandas serileri temel olarak veri çerçevelerinin sütunları olarak kullanılabilmekle birlikte kendi başlarına veri yapıları olarak da kullanılabilirler.

İşe bir pandas.Series nesnesi oluşturarak başlayalım.

In [1]:
import pandas as pd
import numpy as np
gzgn_kutleler = pd.Series([0.330, 4.87, 5.97, 0.642, 1898, 568, 86.8, 102], \
              index=['merkur', 'venus', 'dunya','mars','jupiter', 'saturn', 'uranus', 'neptun'], \
             name="Kutle(10^24 kg)")
print(gzgn_kutleler)
print(gzgn_kutleler.index)
merkur        0.330
venus         4.870
dunya         5.970
mars          0.642
jupiter    1898.000
saturn      568.000
uranus       86.800
neptun      102.000
Name: Kutle(10^24 kg), dtype: float64
Index(['merkur', 'venus', 'dunya', 'mars', 'jupiter', 'saturn', 'uranus',
       'neptun'],
      dtype='object')

Görüldüğü gibi gzgn_kutleler pandas serisini oluşturmak üzere bir listeden sağlanan etiketler (labels ya da index) her bir gezegeni, değerler ise yine bir listeden sağlanan ($10^{24}$ kg cinsinden) kütle değerlerini göstermektedir. Değerleri bir numpy dizisi gibi itere edilebilir (iterable) başka bir değişken türünden de sağlamak mümkündür. Bu anlamda, pandas modülünün Series nesnesi serbest olarak indekslenmiş birer numpy dizisi gibi de düşünülebilir.

pandas serileri etiketsiz (ya da başlıksız) başlatılabileceği gibi, ki bu durumda başlıklar 0'dan başlanarak tam sayılarla numaralandırılır, bir sözlük (dictionary) değişleni üzerinden de tanımlanabilir. Yapıları nedeniyle Pandas series nesnesi, özelleştirilmiş birer dictionary (sözlük) nesnesi gibi de düşünülebilir. Her bir indeks söz konusu seride bir satırdaki değere karşılık gelmektedir.

In [2]:
import numpy as np
s1 = pd.Series(np.random.randn(5)*10)
print(s1)
0     3.232768
1     0.704071
2     6.178762
3   -14.964563
4    19.397352
dtype: float64
In [3]:
yldz_mV = {'Sirius' : -0.5, 'Vega' : 0.0, 'Proxima' : 13.6}
print(type(yldz_mV), yldz_mV)
yldz_mV = pd.Series((yldz_mV))
print(yldz_mV)
<class 'dict'> {'Vega': 0.0, 'Proxima': 13.6, 'Sirius': -0.5}
Proxima    13.6
Sirius     -0.5
Vega        0.0
dtype: float64
In [4]:
pd.Series(yldz_mV, index=['Vega', 'Sirius', 'Altair', 'Proxima'])
Out[4]:
Vega        0.0
Sirius     -0.5
Altair      NaN
Proxima    13.6
dtype: float64
In [5]:
print(yldz_mV.name)
None

series Nesnesi Üzerinde İşlemler

Tıpkı bir numpy dizisi gibi pandas series nesnesi üzerinde işlemler yapılabilir ve fonksiyonlar uygulanabilir, indeksleme ve dilimleme özellikleri kullanılabilir.

In [6]:
print(gzgn_kutleler[::2])
merkur        0.33
dunya         5.97
jupiter    1898.00
uranus       86.80
Name: Kutle(10^24 kg), dtype: float64
In [7]:
print(gzgn_kutleler > gzgn_kutleler['dunya'])
merkur     False
venus      False
dunya      False
mars       False
jupiter     True
saturn      True
uranus      True
neptun      True
Name: Kutle(10^24 kg), dtype: bool
In [8]:
print(gzgn_kutleler[gzgn_kutleler < gzgn_kutleler['uranus'] ])
merkur    0.330
venus     4.870
dunya     5.970
mars      0.642
Name: Kutle(10^24 kg), dtype: float64
In [9]:
print(yldz_mV[1:-1])
print("-----------------")
print(yldz_mV[yldz_mV > yldz_mV.median()])
Sirius   -0.5
dtype: float64
-----------------
Proxima    13.6
dtype: float64
In [10]:
y1 = 'Vega'
y2 = 'Proxima'
print("{:s} ile {:s}'nin aki oranlari {:g}.".\
      format(y1, y2, 10**(-0.4*(yldz_mV[y1]-yldz_mV[y2]))))
Vega ile Proxima'nin aki oranlari 275423.
In [11]:
'Betelgeuse' in yldz_mV
Out[11]:
False
In [12]:
print("Verilen yildizlarin ortalama parlakligi: {:g}, standart sapmasi: {:g}".\
      format(yldz_mV.mean(), yldz_mV.std()))
Verilen yildizlarin ortalama parlakligi: 4.36667, standart sapmasi: 8.00021
In [13]:
s2 = pd.Series(np.random.randn(5)*2.5)
print("s2: \n", s2)
print("s2 + s2: \n" , s2 + s2)
print("s2^2: \n", s2**2)
s2: 
 0    0.197283
1   -2.987800
2   -2.742939
3   -3.392937
4    3.447585
dtype: float64
s2 + s2: 
 0    0.394566
1   -5.975599
2   -5.485877
3   -6.785874
4    6.895170
dtype: float64
s2^2: 
 0     0.038921
1     8.926946
2     7.523712
3    11.512023
4    11.885842
dtype: float64

Bu işlemlerde her iki tarafta aynı başlıkların (indekslerin ya da etiketlerin) olmaması sorunu da pandas tarafından etkin bir şekilde yönetilir.

In [14]:
s2[1:] + s2[:-2]
Out[14]:
0         NaN
1   -5.975599
2   -5.485877
3         NaN
4         NaN
dtype: float64
In [15]:
print(yldz_mV.name)
yldz_mV = yldz_mV.rename('mV')
print(yldz_mV.name)
None
mV

pandas Serilerine Yeni Veriler Ekleme

pandas serilerine (series) yeni seriler append metoduyla eklenir.

In [16]:
print(gzgn_kutleler)
yeni_cisimler = {'pluto':0.0146, 'ay':0.073}
print("------------")
gzgn_kutleler = gzgn_kutleler.append(pd.Series(yeni_cisimler))
print(gzgn_kutleler)
merkur        0.330
venus         4.870
dunya         5.970
mars          0.642
jupiter    1898.000
saturn      568.000
uranus       86.800
neptun      102.000
Name: Kutle(10^24 kg), dtype: float64
------------
merkur        0.3300
venus         4.8700
dunya         5.9700
mars          0.6420
jupiter    1898.0000
saturn      568.0000
uranus       86.8000
neptun      102.0000
ay            0.0730
pluto         0.0146
dtype: float64
In [17]:
print("Saturn'un kutlesi, {:.4f} Jupiter kutlesidir.".format(gzgn_kutleler['saturn'] / gzgn_kutleler['jupiter']))
Saturn'un kutlesi, 0.2993 Jupiter kutlesidir.

Veri Çerçeveleri DataFrames

Pandas serileri her ne kadar veri üzerinde çalışmak için etkin ve hızlı bir yol sağlasa da Pandas'ın asıl veri nesnesi veri çerçeveleridir (DataFrame). Seriler çoğu zaman hızlı bir şekilde veri çerçeveleri oluşturmak üzere ve her veri çerçevesinin sütunları olarak kullanılırlar ve bir boyutludurlar, veri çerçeveleri ise tablolar ve yaygın sayfalar (spreadsheet) olarak düşünülebilir. Bu yapıları nedeniyle Pandas DataFrame nesnelerini, özelleştirilmiş birer dictionary (sözlük) nesnesi olarak da düşünmek mümkündür. Her bir indeks söz konusu veri çerçevesinde bir sütuna karşılık gelir.

Bir Veri Çerçevesi Oluşturmak

Bir DataFrame pek çok açıdan sütun ve satıların isimlerinin olduğu yaygın sayfalara benzer. Yapıları gereği iki boyutuludur (2D). Pandas'la veri analizi büyük ölçüde veri çerçevesi nesnesi üzerine kurulu olduğundan en sık kullanılan nesneler de DataFrame nesneleridir.

Veri çerçeveleri

  • 1 boyutlu listeler (list), sözlükler (dictionary), seriler (series),
  • 2 boyutlu numpy dizileri,
  • Yapılandırılmış ndarray nesneleri,
  • ve diğer veri çerçeveleri kullanılarak tanımlanabilir ya da başlatılabilir.

Dolayısı ile Güneş Sistemi gezegenlerinin bazı özelliklerini saklamak istediğimiz gzgn_kutleler serisi gibi yapıları saklamak için DataFrame daha esnek ve kolay analize olanak sağlayan bir yapı sağlar. Bu seri daha geniş ve gezegenlere ilişkin başka özelliklerin de saklandığı bir gezegenler veri çerçevesinin bir sütununu oluşturabilir.

In [18]:
gezegenler = {'Mg' : gzgn_kutleler,
              'Rg' : pd.Series([2439.5, 6052., 6378., 1737.5, 3396., 71492., 60268., 25559., 24764.,  1185.],\
                    index=['merkur','venus','dunya', 'ay', 'mars', 'jupiter', 'saturn', 'uranus', 'neptun','pluto']),\
            'Prot' : pd.Series([1407.6, -5832.5, 23.9, 655.7, 24.6, 9.9, 10.7, -17.2, 16.1, -153.3],\
                    index=['merkur','venus','dunya', 'ay', 'mars', 'jupiter', 'saturn', 'uranus', 'neptun','pluto']),\
            'Porb' : pd.Series([88.0, 224.7, 365.2, 27.3, 687.0, 4331, 10747, 30589, 59800, 90560], \
                    index=['merkur','venus','dunya', 'ay', 'mars', 'jupiter', 'saturn', 'uranus', 'neptun','pluto'])}

gunes_sistemi = pd.DataFrame(gezegenler)

Veri çerçeveleri pandas serileri kullanılarak oluşturulabileceği gibi listelerden, numpy dizilerinden veya sözlüklerden de oluşturulabilir.

In [19]:
# Sozlukler uzerinden veri cercevesi olusturma
veri = {
    'ogrno' : ['05','12','23','04'],
    'arasinav' : [35, 72, 60, 100], 
    'final' : [70, 43, 57, 82]
}

ders1 = pd.DataFrame(veri)

print(ders1)
   arasinav  final ogrno
0        35     70    05
1        72     43    12
2        60     57    23
3       100     82    04
In [20]:
# Listeler uzerinden veri cercevesi olusturma
sehirler = pd.DataFrame(data = [
['01', 'Adana', 'Kebap'], 
['34', 'Istanbul', 'Kalabalik'], 
['06', 'Ankara', 'Memurlar'], 
['35', 'Izmir', 'Gevrek'], 
['44', 'Malatya', 'Kayisi'], 
['16', 'Bursa', 'Uludag']
], columns = ['Plaka', 'Sehir', 'Ozellik'])

print(sehirler)
  Plaka     Sehir    Ozellik
0    01     Adana      Kebap
1    34  Istanbul  Kalabalik
2    06    Ankara   Memurlar
3    35     Izmir     Gevrek
4    44   Malatya     Kayisi
5    16     Bursa     Uludag
In [21]:
# Numpy dizileri uzerinden veri cercevesi olusturma
tarihler = pd.date_range('20200219', periods=5)
df = pd.DataFrame(np.random.randn(5, 4), index=tarihler, columns=list('ABCD'))
print(df)
                   A         B         C         D
2020-02-19  0.326853  1.095298 -0.665982 -0.676471
2020-02-20 -0.690708 -1.305939 -0.523247  1.619419
2020-02-21 -0.151111 -0.801184 -2.125244  1.019877
2020-02-22  1.620920  0.117473 -0.237913  1.079924
2020-02-23 -0.944600 -0.783388  0.602502 -1.405102
In [22]:
# Birden fazla nesne turu kullanarak veri cercevesi olusturma
df2 = pd.DataFrame({'A': 1.,
                    'B': pd.Timestamp('20190219'),
                    'C': pd.Series(1, index=list(range(4)), dtype='float32'),
                    'D': np.array([3] * 4, dtype='int32'),
                    'E': pd.Categorical(["AST413", "AST415", "AST416", "AST515"]),
                    'F': 'Asterosismoloji'})

print(df2)
     A          B    C  D       E                F
0  1.0 2019-02-19  1.0  3  AST413  Asterosismoloji
1  1.0 2019-02-19  1.0  3  AST415  Asterosismoloji
2  1.0 2019-02-19  1.0  3  AST416  Asterosismoloji
3  1.0 2019-02-19  1.0  3  AST515  Asterosismoloji

Veri Çerçevelerinin Görüntülenmesi

Veri çerçevelerinin tamamını, bir bölümünü, bir sütununu, bir satırını ya da bir elemanını görüntülemek için pek çok fonksiyon bulunduğu gibi listelerde ve dizilerde geçerli dilimleme ve indeksleme seçenekleri de kullanılabilmektedir.

In [23]:
print("Tun Gunes Sistemi")
print(gunes_sistemi)
print("---------------------")
print("Veri cercevesindeki ilk 5 gezegen")
print(gunes_sistemi.head())
print("---------------------")
print("Veri cercevesindeki son 3 gezegen")
print(gunes_sistemi.tail(3))
print("---------------------")
print("Kutleler : ")
print(gunes_sistemi['Mg']*1e24)
print("Ortalama Kutle: {:g} kg".format(gunes_sistemi['Mg'].mean()*1e24))
print("----------------------")
Tun Gunes Sistemi
                Mg     Porb    Prot       Rg
ay          0.0730     27.3   655.7   1737.5
dunya       5.9700    365.2    23.9   6378.0
jupiter  1898.0000   4331.0     9.9  71492.0
mars        0.6420    687.0    24.6   3396.0
merkur      0.3300     88.0  1407.6   2439.5
neptun    102.0000  59800.0    16.1  24764.0
pluto       0.0146  90560.0  -153.3   1185.0
saturn    568.0000  10747.0    10.7  60268.0
uranus     86.8000  30589.0   -17.2  25559.0
venus       4.8700    224.7 -5832.5   6052.0
---------------------
Veri cercevesindeki ilk 5 gezegen
               Mg    Porb    Prot       Rg
ay          0.073    27.3   655.7   1737.5
dunya       5.970   365.2    23.9   6378.0
jupiter  1898.000  4331.0     9.9  71492.0
mars        0.642   687.0    24.6   3396.0
merkur      0.330    88.0  1407.6   2439.5
---------------------
Veri cercevesindeki son 3 gezegen
            Mg     Porb    Prot       Rg
saturn  568.00  10747.0    10.7  60268.0
uranus   86.80  30589.0   -17.2  25559.0
venus     4.87    224.7 -5832.5   6052.0
---------------------
Kutleler : 
ay         7.300000e+22
dunya      5.970000e+24
jupiter    1.898000e+27
mars       6.420000e+23
merkur     3.300000e+23
neptun     1.020000e+26
pluto      1.460000e+22
saturn     5.680000e+26
uranus     8.680000e+25
venus      4.870000e+24
Name: Mg, dtype: float64
Ortalama Kutle: 2.6667e+26 kg
----------------------
In [24]:
print(gunes_sistemi.columns)
Index(['Mg', 'Porb', 'Prot', 'Rg'], dtype='object')

describe metodu ile veri setinin bazı istatistiksel parametrelerini görmek ve veri seti hakkında hızlı bir yorumda bulunmak da mümkün olabilir.

In [25]:
print(gunes_sistemi.describe())
                Mg         Porb         Prot           Rg
count    10.000000     10.00000    10.000000     10.00000
mean    266.669960  19741.92000  -385.450000  20327.10000
std     599.249294  31535.38816  1971.154887  25770.69571
min       0.014600     27.30000 -5832.500000   1185.00000
25%       0.408000    259.82500   -10.425000   2678.62500
50%       5.420000   2509.00000    13.400000   6215.00000
75%      98.200000  25628.50000    24.425000  25360.25000
max    1898.000000  90560.00000  1407.600000  71492.00000

Veri çerçevesini herhangi bir eksene göre sıralamak için sort_values fonksiyonu kullanılır.

In [26]:
gunes_sistemi.sort_values(by='Rg')
Out[26]:
Mg Porb Prot Rg
pluto 0.0146 90560.0 -153.3 1185.0
ay 0.0730 27.3 655.7 1737.5
merkur 0.3300 88.0 1407.6 2439.5
mars 0.6420 687.0 24.6 3396.0
venus 4.8700 224.7 -5832.5 6052.0
dunya 5.9700 365.2 23.9 6378.0
neptun 102.0000 59800.0 16.1 24764.0
uranus 86.8000 30589.0 -17.2 25559.0
saturn 568.0000 10747.0 10.7 60268.0
jupiter 1898.0000 4331.0 9.9 71492.0

Veri Çerçevelerinin Dilimlenmesi ve İndekslenmesi

İndeksleme ve dilimleme işlemleri tıpkı numpy, list, tuple nesenlerinde ve pd.Series nesnesinde yapıldığı şekliyle yapılabilir. Bunun dışındaki işlemler için:

  • Sütın seçme: df[col] (ilgili sütundaki seriyi getirir)
  • Satır seçme: df.loc[label] (ilgii satırdaki seriyi getirir)
  • Satırı indeks değeri ile seçme: df.iloc[loc] (ilgii satırdaki seriyi getirir)
  • Satırda dilimleme: df[5:10] (Veri çerçevesinin dilimlenmiş bölümünü getirir)
  • Satırı bir koşulla seçme: df[kosul] (Veri çerçevesinin koşula uyan bölümünü)

yapıarı da kullanılabilir. Öncelikle numpy dizilerindeki indeksleme tarzı indeksleme seçeneklerini gözden geçirelim.

In [27]:
gunes_sistemi[::2]
Out[27]:
Mg Porb Prot Rg
ay 0.0730 27.3 655.7 1737.5
jupiter 1898.0000 4331.0 9.9 71492.0
merkur 0.3300 88.0 1407.6 2439.5
pluto 0.0146 90560.0 -153.3 1185.0
uranus 86.8000 30589.0 -17.2 25559.0
In [28]:
gunes_sistemi[-1:0:-2]
Out[28]:
Mg Porb Prot Rg
venus 4.870 224.7 -5832.5 6052.0
saturn 568.000 10747.0 10.7 60268.0
neptun 102.000 59800.0 16.1 24764.0
mars 0.642 687.0 24.6 3396.0
dunya 5.970 365.2 23.9 6378.0

Kullanıcı Tanımlı İndeksler ve Konuma Bağlı İndeksler

İndekslemede tamsayı indekslere başvurarak verilerin yeri üzerinden yukarıdaki gibi indeksleme yapılabileeği gibi (ing. implicit indexes), Series ve DataFrame nesnelerinin indeksleri (satır isimleri olarak da düşünülebilir) olduğu düşüncesinden hareketle bu indeksler üzerinden de dilimleme ve indeksleme (ing. explicit indexes) yapılabilir.

In [29]:
gunes_sistemi['jupiter':'pluto']
Out[29]:
Mg Porb Prot Rg
jupiter 1898.0000 4331.0 9.9 71492.0
mars 0.6420 687.0 24.6 3396.0
merkur 0.3300 88.0 1407.6 2439.5
neptun 102.0000 59800.0 16.1 24764.0
pluto 0.0146 90560.0 -153.3 1185.0

Bu durumda özellikle tamsayı indeksler seçilerek kullanıcı tarafından oluşturulmuş veri çerçeveleri ve seriler üzerinde çalışılırken, kullanıcının belirlediği indekslerin mi yoksa verinin bulunduğu yerin indekslerinin mi geçerli olduğu gibi bir soru ortaya çıkar. Bunu basit bir örnekle görelim.

In [30]:
seri_tamindeks = pd.Series(['merkur', 'dunya', 'jupiter'], index=[1, 3, 5])
#Indeksleme yapilirken kullanici tanimli indeksler kullanilirken
print(seri_tamindeks[1]) 
print("---------------")
#Dilimlemede verinin yerine dayali indeksler kullanilir
print(seri_tamindeks[0:2])
merkur
---------------
1    merkur
3     dunya
dtype: object

Bu karışıklığı önlemek için Pandas, bazı dizinleme şemalarını esas alan özel dizin oluşturucu özellikler (attributes) sağlar. Bunları pandas nesneleri üzerinde tanımlı fonksiyonlar metotlar (methods) olarak değil, o nesneye özel özellikler olarak düşünmek gerekir.

loc attribute'ı her zaman kullanıcı tarafından verilen indekslere referans vermek için kullanılır.

In [31]:
# seri_tamindeks uzerinde bu kez kullanici indeksiyle veri secelim
print(seri_tamindeks.loc[5])
jupiter
In [32]:
# Gunes Sistemi veri cercevesi uzerinde
# Herhangi satir(lar)i indeksiyle secmek icin
gunes_sistemi.loc['jupiter']
Out[32]:
Mg       1898.0
Porb     4331.0
Prot        9.9
Rg      71492.0
Name: jupiter, dtype: float64

Kullanıcı Tanımlı İndekslerle Seçim ve Dilimleme

Dilimlemede kullanıcı tanımlı indeksler üzerinden dilimleme yapılırken verilen aralığın her iki ucu da (sonu da!) dilimlememey dahil edilirken, numpy dizisi (ya da liste) tarzı, verinin bulunduğu konuma göre yapılan indekslemede verilen aralığın sonu dilimlemeye dahil edilmez (örn. $dizi[1:4]$ şeklinde bir indekslemede dizinin 1, 2 ve 3 numaralı indekslerinde bulunan değerlerden bir dizi dilimi oluşturulur, 4 numaralı indeksteki değer alınmaz!).

In [33]:
# Veri cercevesinin sadece bir bolumunu secmek icin
gunes_sistemi.loc['jupiter':'merkur', ['Mg', 'Rg']]
Out[33]:
Mg Rg
jupiter 1898.000 71492.0
mars 0.642 3396.0
merkur 0.330 2439.5
In [34]:
gunes_sistemi.loc['ay', ['Prot','Porb']]
Out[34]:
Prot    655.7
Porb     27.3
Name: ay, dtype: float64

loc kullanılarak sütun ya da satır adıyla seçim yapılabileceği gibi indeks numarası kullanılarak verinin bulundğu konum üzerinden de seçim yapılabilir; bunun için iloc attribute'una başvurulur.

In [35]:
# seri_tamindeks serisi uzerinde
seri_tamindeks.iloc[2]
seri_tamindeks.iloc[0:2]
Out[35]:
1    merkur
3     dunya
dtype: object
In [36]:
gunes_sistemi.iloc[4]
Out[36]:
Mg         0.33
Porb      88.00
Prot    1407.60
Rg      2439.50
Name: merkur, dtype: float64
In [37]:
gunes_sistemi.sort_values('Porb').iloc[3]
Out[37]:
Mg         5.97
Porb     365.20
Prot      23.90
Rg      6378.00
Name: dunya, dtype: float64
In [38]:
gunes_sistemi.sort_values('Porb').iloc[1:5,2:4]
Out[38]:
Prot Rg
merkur 1407.6 2439.5
venus -5832.5 6052.0
dunya 23.9 6378.0
mars 24.6 3396.0
In [39]:
gunes_sistemi.iloc[[4,3,0],-1]
Out[39]:
merkur    2439.5
mars      3396.0
ay        1737.5
Name: Rg, dtype: float64
In [40]:
# Belirli bir deger icin
print(gunes_sistemi.loc['venus','Rg'])
print(gunes_sistemi.iloc[-1, -1])
6052.0
6052.0
In [41]:
# Bu islemi daha hizli yapabilen iki metot at ve iat metotlaridir
print(gunes_sistemi.at['dunya','Mg'])
print(gunes_sistemi.iat[1,2]) #1: dunya 2: Porb
5.97
23.9

Tıpkı numpy dizilerinde olduğu gibi pandas veri çerçevelerinde de bir koşula dayanan dilimleemler yapılabilir.

In [42]:
print(gunes_sistemi['Porb'] > 365.25)
ay         False
dunya      False
jupiter     True
mars        True
merkur     False
neptun      True
pluto       True
saturn      True
uranus      True
venus      False
Name: Porb, dtype: bool
In [43]:
print(gunes_sistemi[gunes_sistemi['Mg'] > 10.00]['Rg'])
jupiter    71492.0
neptun     24764.0
saturn     60268.0
uranus     25559.0
Name: Rg, dtype: float64

Bir koşula göre dilimlemelerde dahi numpy tarzı dilimlemeler ve indekslemelerin dahi pandas tarafından sağlanan loc, iloc, ix, at, iatözellikleri (attribute) kullanılması önerilmektedir.

In [44]:
print(gunes_sistemi.loc[gunes_sistemi['Prot'] < 24.0])
                Mg     Porb    Prot       Rg
dunya       5.9700    365.2    23.9   6378.0
jupiter  1898.0000   4331.0     9.9  71492.0
neptun    102.0000  59800.0    16.1  24764.0
pluto       0.0146  90560.0  -153.3   1185.0
saturn    568.0000  10747.0    10.7  60268.0
uranus     86.8000  30589.0   -17.2  25559.0
venus       4.8700    224.7 -5832.5   6052.0

Herhangi bir değerin bir sütunda olup olmadığını belirlemek için isin fonksiyonu kullanılır.

In [45]:
gunes_sistemi[gunes_sistemi['Porb'].isin([365.2, 88.00])]
Out[45]:
Mg Porb Prot Rg
dunya 5.97 365.2 23.9 6378.0
merkur 0.33 88.0 1407.6 2439.5

Veri Çerçevelerinde Değişiklik Yapmak

Veri Çerçevelerine Sütun Eklemek

Veri çerçevesine bir sütun eklenmek istenirken indeksler (satırların isimleri ya da indeks numaraları) verilmezse satırların sırası takip edilir.

In [46]:
print(df)
                   A         B         C         D
2020-02-19  0.326853  1.095298 -0.665982 -0.676471
2020-02-20 -0.690708 -1.305939 -0.523247  1.619419
2020-02-21 -0.151111 -0.801184 -2.125244  1.019877
2020-02-22  1.620920  0.117473 -0.237913  1.079924
2020-02-23 -0.944600 -0.783388  0.602502 -1.405102
In [47]:
s1 = [1, 2, 3, 4, 5]
df['E'] = s1
print(df)
                   A         B         C         D  E
2020-02-19  0.326853  1.095298 -0.665982 -0.676471  1
2020-02-20 -0.690708 -1.305939 -0.523247  1.619419  2
2020-02-21 -0.151111 -0.801184 -2.125244  1.019877  3
2020-02-22  1.620920  0.117473 -0.237913  1.079924  4
2020-02-23 -0.944600 -0.783388  0.602502 -1.405102  5

Ancak indeksleri vererek yeni bir sütun eklemek daha güvenilir ve tutarlı bir yoldur.

In [48]:
gunes_sistemi['e'] = pd.Series([0.205, 0.007, 0.017, 0.055, 0.094, 0.049, 0.057, 0.046, 0.011, 0.244], \
                              index = ['merkur','venus', 'dunya', 'ay', 'mars', 'jupiter', 'saturn', 'uranus', 'neptun', 'pluto'])
print(gunes_sistemi)
                Mg     Porb    Prot       Rg      e
ay          0.0730     27.3   655.7   1737.5  0.055
dunya       5.9700    365.2    23.9   6378.0  0.017
jupiter  1898.0000   4331.0     9.9  71492.0  0.049
mars        0.6420    687.0    24.6   3396.0  0.094
merkur      0.3300     88.0  1407.6   2439.5  0.205
neptun    102.0000  59800.0    16.1  24764.0  0.011
pluto       0.0146  90560.0  -153.3   1185.0  0.244
saturn    568.0000  10747.0    10.7  60268.0  0.057
uranus     86.8000  30589.0   -17.2  25559.0  0.046
venus       4.8700    224.7 -5832.5   6052.0  0.007
In [49]:
# g/cm^3 cinsinden hacimleri yeni bir sutuna ekleyelim
gunes_sistemi['V'] = gunes_sistemi['Mg']*1e27 / (4./3*np.pi*(gunes_sistemi['Rg']*1e5)**3)
print(gunes_sistemi)
                Mg     Porb    Prot       Rg      e         V
ay          0.0730     27.3   655.7   1737.5  0.055  3.322460
dunya       5.9700    365.2    23.9   6378.0  0.017  5.493286
jupiter  1898.0000   4331.0     9.9  71492.0  0.049  1.240039
mars        0.6420    687.0    24.6   3396.0  0.094  3.913302
merkur      0.3300     88.0  1407.6   2439.5  0.205  5.426538
neptun    102.0000  59800.0    16.1  24764.0  0.011  1.603427
pluto       0.0146  90560.0  -153.3   1185.0  0.244  2.094639
saturn    568.0000  10747.0    10.7  60268.0  0.057  0.619440
uranus     86.8000  30589.0   -17.2  25559.0  0.046  1.241079
venus       4.8700    224.7 -5832.5   6052.0  0.007  5.244977

Veri Çerçevelerine Satır Eklemek

Şimdi aslında bir cüce gezegen olmasına karşın Ceres'in parametrelerini yeni bir satır olarak veri çerçevemize ekleyelim ama Ceres'in yörünge dönemini ($P_{orb}$) ve dış merkezliliğini ($e$) girmeyi unutmuş olalım. Ayrıca diğer parameterleri de bir miktar "karışık" bir sırada verelim. Bunun yanı sıra Ceres'in yarıçapını da Dünya yarıçapı cinsinden ($R = 0.074 R_{dunya}$) biliyor olalım.

In [50]:
ceres =  {'Prot' : pd.Series([9.1], index=['ceres']),\
         'Rg' : pd.Series([0.074*gunes_sistemi.at['dunya','Rg']], index=['ceres']),\
         'Mg': pd.Series([0.94e-3], index=['ceres'])}
gunes_sistemi = gunes_sistemi.append(pd.DataFrame(ceres), sort=True)
print(gunes_sistemi)
                 Mg     Porb    Prot         Rg         V      e
ay          0.07300     27.3   655.7   1737.500  3.322460  0.055
dunya       5.97000    365.2    23.9   6378.000  5.493286  0.017
jupiter  1898.00000   4331.0     9.9  71492.000  1.240039  0.049
mars        0.64200    687.0    24.6   3396.000  3.913302  0.094
merkur      0.33000     88.0  1407.6   2439.500  5.426538  0.205
neptun    102.00000  59800.0    16.1  24764.000  1.603427  0.011
pluto       0.01460  90560.0  -153.3   1185.000  2.094639  0.244
saturn    568.00000  10747.0    10.7  60268.000  0.619440  0.057
uranus     86.80000  30589.0   -17.2  25559.000  1.241079  0.046
venus       4.87000    224.7 -5832.5   6052.000  5.244977  0.007
ceres       0.00094      NaN     9.1    471.972       NaN    NaN

Eklemeyi bir veri serisi üzerinden değil bir sözlük üzerinden de yapabiliriz. Güneş Sistemi'nin en büyük uydusu Ganymede'in bildiğimiz parametrelerini de bu şekilde ekleyelim.

In [51]:
ganymede = {'Mg' : 148.2e-3, 'Rg' : 2631., 'e' : 0.001}
gunes_sistemi = gunes_sistemi.append(pd.DataFrame(ganymede, index=['ganymede']), \
                                     sort=True)
print(gunes_sistemi)
                  Mg     Porb    Prot         Rg         V      e
ay           0.07300     27.3   655.7   1737.500  3.322460  0.055
dunya        5.97000    365.2    23.9   6378.000  5.493286  0.017
jupiter   1898.00000   4331.0     9.9  71492.000  1.240039  0.049
mars         0.64200    687.0    24.6   3396.000  3.913302  0.094
merkur       0.33000     88.0  1407.6   2439.500  5.426538  0.205
neptun     102.00000  59800.0    16.1  24764.000  1.603427  0.011
pluto        0.01460  90560.0  -153.3   1185.000  2.094639  0.244
saturn     568.00000  10747.0    10.7  60268.000  0.619440  0.057
uranus      86.80000  30589.0   -17.2  25559.000  1.241079  0.046
venus        4.87000    224.7 -5832.5   6052.000  5.244977  0.007
ceres        0.00094      NaN     9.1    471.972       NaN    NaN
ganymede     0.14820      NaN     NaN   2631.000       NaN  0.001

İki büyük uydunun (Titan, Triton) parametrelerini daha ekleyelim.

In [52]:
iki_buyuk_uydu = [{'Mg':134.6e-3, 'Rg':2575, 'Prot':382.7, 'e': 0.029}, \
            {'Rg':1352.5, 'Prot':-141.0, 'e':0.000, 'Mg':21.5e-3}]
gunes_sistemi = gunes_sistemi.append(pd.DataFrame(iki_buyuk_uydu, \
                                                  index=['titan','triton']), sort=True)
print(gunes_sistemi)
                  Mg     Porb    Prot         Rg         V      e
ay           0.07300     27.3   655.7   1737.500  3.322460  0.055
dunya        5.97000    365.2    23.9   6378.000  5.493286  0.017
jupiter   1898.00000   4331.0     9.9  71492.000  1.240039  0.049
mars         0.64200    687.0    24.6   3396.000  3.913302  0.094
merkur       0.33000     88.0  1407.6   2439.500  5.426538  0.205
neptun     102.00000  59800.0    16.1  24764.000  1.603427  0.011
pluto        0.01460  90560.0  -153.3   1185.000  2.094639  0.244
saturn     568.00000  10747.0    10.7  60268.000  0.619440  0.057
uranus      86.80000  30589.0   -17.2  25559.000  1.241079  0.046
venus        4.87000    224.7 -5832.5   6052.000  5.244977  0.007
ceres        0.00094      NaN     9.1    471.972       NaN    NaN
ganymede     0.14820      NaN     NaN   2631.000       NaN  0.001
titan        0.13460      NaN   382.7   2575.000       NaN  0.029
triton       0.02150      NaN  -141.0   1352.500       NaN  0.000

Şimdi bakınca Ganymede'in dönme dönemini girmediğimizi farketmiş ve girmek istiyor olalım. Uydular için yörünge dönemi gezegenlerinin etrafındaki yörüngelerinin dönemi olduğu için girmemeyi tercih ettik (Ay hariç).

In [53]:
gunes_sistemi.at['ganymede', 'Prot'] = 171.7
print(gunes_sistemi)
                  Mg     Porb    Prot         Rg         V      e
ay           0.07300     27.3   655.7   1737.500  3.322460  0.055
dunya        5.97000    365.2    23.9   6378.000  5.493286  0.017
jupiter   1898.00000   4331.0     9.9  71492.000  1.240039  0.049
mars         0.64200    687.0    24.6   3396.000  3.913302  0.094
merkur       0.33000     88.0  1407.6   2439.500  5.426538  0.205
neptun     102.00000  59800.0    16.1  24764.000  1.603427  0.011
pluto        0.01460  90560.0  -153.3   1185.000  2.094639  0.244
saturn     568.00000  10747.0    10.7  60268.000  0.619440  0.057
uranus      86.80000  30589.0   -17.2  25559.000  1.241079  0.046
venus        4.87000    224.7 -5832.5   6052.000  5.244977  0.007
ceres        0.00094      NaN     9.1    471.972       NaN    NaN
ganymede     0.14820      NaN   171.7   2631.000       NaN  0.001
titan        0.13460      NaN   382.7   2575.000       NaN  0.029
triton       0.02150      NaN  -141.0   1352.500       NaN  0.000

Veri Çerçevelerinden Satır ya da Sütun Silmek

Veri çerçevelerinden sütun silmek için del komutu (zira bir veri çerçevesi değiştirilemez (ing. immutable) bir nesnedir), satır silmek için ise drop metodu kullanılır.

In [54]:
print(sehirler)
sehirler['Bolge'] = ['Akdeniz', 'Marmara', 'Ic Anadolu', 'Ege', 'Guneydogu Anadolu', 'Marmara']
print(sehirler)
del sehirler['Ozellik']
print(sehirler)
  Plaka     Sehir    Ozellik
0    01     Adana      Kebap
1    34  Istanbul  Kalabalik
2    06    Ankara   Memurlar
3    35     Izmir     Gevrek
4    44   Malatya     Kayisi
5    16     Bursa     Uludag
  Plaka     Sehir    Ozellik              Bolge
0    01     Adana      Kebap            Akdeniz
1    34  Istanbul  Kalabalik            Marmara
2    06    Ankara   Memurlar         Ic Anadolu
3    35     Izmir     Gevrek                Ege
4    44   Malatya     Kayisi  Guneydogu Anadolu
5    16     Bursa     Uludag            Marmara
  Plaka     Sehir              Bolge
0    01     Adana            Akdeniz
1    34  Istanbul            Marmara
2    06    Ankara         Ic Anadolu
3    35     Izmir                Ege
4    44   Malatya  Guneydogu Anadolu
5    16     Bursa            Marmara
In [55]:
sehirler.drop(4, axis=0)
Out[55]:
Plaka Sehir Bolge
0 01 Adana Akdeniz
1 34 Istanbul Marmara
2 06 Ankara Ic Anadolu
3 35 Izmir Ege
5 16 Bursa Marmara
In [56]:
print(sehirler)
  Plaka     Sehir              Bolge
0    01     Adana            Akdeniz
1    34  Istanbul            Marmara
2    06    Ankara         Ic Anadolu
3    35     Izmir                Ege
4    44   Malatya  Guneydogu Anadolu
5    16     Bursa            Marmara

Pandas Veri Nesneleri Üzerinde Fonksiyon Kullanımı

Pandas özünde numpy dizileriyle de birlikte çalışmak üzere tasarlanmış bir veri yönetim paketi olduğu için diziler üzerinde çalışabilen ön tanımlı (built-in) ya da kullanıcı tanımlı fonksiyonlar Pandas veri nesneleri üzerinde çallışır.

In [57]:
import pandas as pd
import numpy as np
rstglvr = np.random.RandomState(42)
rstglsr = pd.Series(rstglvr.randint(0, 20, 5))
rstglsr
Out[57]:
0     6
1    19
2    14
3    10
4     7
dtype: int64
In [58]:
rstgldf = pd.DataFrame(rstglvr.randint(0, 20, (4, 5)),
columns=['A', 'B', 'C', 'D', 'E'])
rstgldf
Out[58]:
A B C D E
0 6 18 10 10 3
1 7 2 1 11 5
2 1 0 11 11 16
3 9 15 14 14 18
In [59]:
print(np.sin(rstgldf/16. + np.pi / 2))
          A         B         C         D         E
0  0.930508  0.431177  0.810963  0.810963  0.982473
1  0.905814  0.992198  0.998048  0.772835  0.951568
2  0.998048  1.000000  0.772835  0.772835  0.540302
3  0.845924  0.591805  0.640997  0.640997  0.431177

Herhangi bir fonksiyon ya da aritmetik işlem birden fazla seri ya da veri çerçevesi arasında uygulanmak istendiğinde Pandas iki veri nesnesinin indekslerini hizalar.

In [60]:
yuzolcum = pd.Series({'Birlesik Krallik': 242495, 'Fransa': 551695, 'Almanya': 357386, 
'Ispanya': 498511, 'Turkiye': 783562}, name='yuzolcum')
nufus = pd.Series({'Turkiye': 84200851, 'Ispanya': 46767543, 'Birlesik Krallik': 67803450,
'Almanya': 83792987, 'Fransa': 65227357}, name='yuzolcum')
nufus_yogunlugu = nufus / yuzolcum
print(nufus_yogunlugu)
Almanya             234.460743
Birlesik Krallik    279.607621
Fransa              118.230829
Ispanya              93.814465
Turkiye             107.459079
Name: yuzolcum, dtype: float64
In [61]:
gdp = pd.Series({'Almanya': 3863344, 'Fransa': 2707074, 'Italya': 1988636, 
'Izlanda': 24280, 'Turkiye': 743708}, name='yuzolcum')
gdp_kisibasi = gdp / nufus
print(gdp_kisibasi*1e6)
Almanya             46105.815514
Birlesik Krallik             NaN
Fransa              41502.126171
Ispanya                      NaN
Italya                       NaN
Izlanda                      NaN
Turkiye              8832.547310
Name: yuzolcum, dtype: float64

Bir veri çerçevesi ile bir seri arasında işlem yaparken işlem varsayılan olarak satırda gerçekleşir ve indeksler hizalanır.

In [62]:
A = rstglvr.randint(20, size=(4, 5))
dfA = pd.DataFrame(A, columns=list('XYZTW'))
dfA - dfA.iloc[0]
Out[62]:
X Y Z T W
0 0 0 0 0 0
1 -5 -11 4 13 -15
2 2 -2 6 -3 1
3 3 -13 9 3 -4

İşlem sütun üzerinde yapılmak istendiğinde axis anahtarı işlemin sütun üzerinden yapılacağını belirtmek üzere $0$ 'a eşitlenir

In [63]:
print(dfA)
dfA.subtract(dfA['Z'], axis=0)
    X   Y   Z   T   W
0  11  19   2   4  18
1   6   8   6  17   3
2  13  17   8   1  19
3  14   6  11   7  14
Out[63]:
X Y Z T W
0 9 17 0 2 16
1 0 2 0 11 -3
2 5 9 0 -7 11
3 3 -5 0 -4 3

Apply Metodu

apply metodu herhangi bir fonksiyonun tüm veriçerçevesi ya da seri üzerine uygulanmasını sağlar.

In [64]:
import pandas as pd
import numpy as np
rstglvr = np.random.RandomState(42)
print(rstglvr)
A = rstglvr.randn(20)
dfA = pd.DataFrame(A.reshape((4,5)), columns=list('XYZTW'))
print(dfA)
print(dfA.apply(np.cumsum))
RandomState(MT19937)
          X         Y         Z         T         W
0  0.496714 -0.138264  0.647689  1.523030 -0.234153
1 -0.234137  1.579213  0.767435 -0.469474  0.542560
2 -0.463418 -0.465730  0.241962 -1.913280 -1.724918
3 -0.562288 -1.012831  0.314247 -0.908024 -1.412304
          X         Y         Z         T         W
0  0.496714 -0.138264  0.647689  1.523030 -0.234153
1  0.262577  1.440949  1.415123  1.053555  0.308407
2 -0.200840  0.975219  1.657086 -0.859725 -1.416511
3 -0.763128 -0.037612  1.971333 -1.767749 -2.828815

Girilmeyen Verilerin Yönetimi

Bir veri tablosuna ya da pandas diliyle veri çerçevesinde karşılığı bulunmayan bir verinin nasıl girileceği tartışmalı bir konu olup, tek bir çözümü de yoktur. Veri türüne bağlı olarak bazı durumlarda $-1$, $9.9999$, $-99999$ gibi "nöbetçi değer" (ing. sentinel) kullanılabileceği gibi, boş bırakmak, '-', 'NA', 'N/A'gibi belirteçler kullanmak da tercih edilebilmektedir. Bu çözümlerin her birinin avantaj ve dezavantajları bulunur. Örneğin tüm verilerin pozitif olarak girileceği bir sütunda değeri olmayanların yerine $-1$ girmek sütunlar üzerinde matematiksel işlemler yapılırken bu sütunun da dikkate alınması ve CPU'ya bu nedenle ek yük binmesi anlamına gelir.

Pandas, bir veri çerçevesi ya da seride bulunmayacak verilerin yerine $None$ ve $NaN$ nesnelerini kullanır. Ancak $None$ kullanıldığına veri tipi de nesne ($object$) olur ki bu işlemlerin daha kısa sürede yapılmasına olanak sağlayan $NaN$ seçeneğine göre dezavantajlıdır.

In [65]:
for dtype in ['object', 'int']:
    print("dtype =", dtype)
    %timeit np.arange(1E6, dtype=dtype).sum()
    print()
dtype = object
72.7 ms ± 3.25 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

dtype = int
2.01 ms ± 99.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

NaN Veri Türü

$NaN$ veri türü IEEE kayan noktalı sayı standartları arasında tanımlanmış ve tüm programlama dilleri ve dijital işlemlerde kullanılan bir veri türüdür. $NaN$ veri türü ile yapılan tüm işlemler sonuç döndürür.

In [66]:
x = np.array([1, np.nan, 3, 4])
print("1 + x = ", 1 + x)
print("0x = ", 0*x)
print("ln(x) = ", np.log(x))
print("min(x) = ", np.min(x))
print("nanmax(x) = ", np.nanmax(x))
print("SIGMA(x) = ", np.sum(x))
print("nansum(x) = ", np.nansum(x))
1 + x =  [ 2. nan  4.  5.]
0x =  [ 0. nan  0.  0.]
ln(x) =  [0.                nan 1.09861229 1.38629436]
min(x) =  nan
nanmax(x) =  4.0
SIGMA(x) =  nan
nansum(x) =  8.0

pandas modülünde girilmeyen ya da NaN (ing. Not a Number) veya None olarak girilen verileri (Null) yönetmek üzere de özel fonksiyonlar (isnull, notnull,dropna,fillna) bulunmaktadır.

In [67]:
veri2 = {
    'ogrno' : ['08','16','32','74'],
    'odev' : [56, 72, 60, 84], 
    'proje' : [70, 43, 57, 71]
}
ders2 = pd.DataFrame(veri2)
ders2
Out[67]:
odev ogrno proje
0 56 08 70
1 72 16 43
2 60 32 57
3 84 74 71
In [68]:
ders2 = ders2.append(pd.DataFrame({'ogrno' : 18, 'proje' : 37}, 
                                  index=[4]), sort=True)
ders2
Out[68]:
odev ogrno proje
0 56.0 08 70
1 72.0 16 43
2 60.0 32 57
3 84.0 74 71
4 NaN 18 37
In [69]:
ders2 = ders2.append(pd.DataFrame({'ogrno' : 24, 'odev' : 65}, 
                                  index=[5]), sort=True)
ders2
Out[69]:
odev ogrno proje
0 56.0 08 70.0
1 72.0 16 43.0
2 60.0 32 57.0
3 84.0 74 71.0
4 NaN 18 37.0
5 65.0 24 NaN

Nan olan değerlerin tablodaki yerini isna fonksiyonuyla görebiliriz.

In [70]:
# isna fonksiyonu Null degeri veren elemanlari True
# digerlerini False isaretleyerek bir maske (mask) olusturur 
pd.isna(ders2)
Out[70]:
odev ogrno proje
0 False False False
1 False False False
2 False False False
3 False False False
4 True False False
5 False False True

dropna Fonksiyonu

dropna $NaN$ değer bulunan satır (varsayılan) ya da sütunları silmek için kullanılır.

In [71]:
ders2.dropna(subset=['proje'])
Out[71]:
odev ogrno proje
0 56.0 08 70.0
1 72.0 16 43.0
2 60.0 32 57.0
3 84.0 74 71.0
4 NaN 18 37.0

Varsayılan davranışında satır silen drop fonksiyonu NaN sütunları silmek için de kullanılabilir. $axis = 1$ ya da $axis = columns$ verilerek NaN barındıran tüm sütunlar silinebilir.

In [72]:
ders2.dropna(axis=1)
Out[72]:
ogrno
0 08
1 16
2 32
3 74
4 18
5 24

dropna fonksiyonunun how parametresi en az bir değeri ($how = 'any'$) veya tüm değerleri ($how = 'all'$) NaN olan, satır veya sütunun veri çerçevesinden kaldırılıp kaldırılmayacağını belirler.

In [73]:
ders2.dropna(how='any')
Out[73]:
odev ogrno proje
0 56.0 08 70.0
1 72.0 16 43.0
2 60.0 32 57.0
3 84.0 74 71.0

fillna Fonksiyonu

Bazen $NA$ değerlerini silmek yerine, geçerli bir değerle değiştirmek tercih edilebilir. Bu değer, sıfır gibi tek bir sayı olabilir veya çevredeki değerler kullanılarak yapılabilecek bir interpolasyon sonucu elde edilen değer olabilir. Aslında bu işlem isnull fonksiyonu ile bir maske (ing. mask) üretilerek $NaN$ değerler belirlendikten sonra istenen değerlerle değiştirilerek de yapılabilir. Ancak bu çok sık kullanılan işlem olduğu için Pandas dizinin bir kopyasını $null$ değerlerle değiştiren fillna metodunu sağlamıştır.

In [74]:
veri = pd.Series([1, np.nan, 2, None, 3, np.nan], index=list('PQRSTU'))
veri
Out[74]:
P    1.0
Q    NaN
R    2.0
S    NaN
T    3.0
U    NaN
dtype: float64
In [75]:
# NaN degerleri 0 ile degistir
veri.fillna(0)
Out[75]:
P    1.0
Q    0.0
R    2.0
S    0.0
T    3.0
U    0.0
dtype: float64
In [76]:
# Nan degerleri bir sonraki deger ile degistir
veri.fillna(method='ffill')
Out[76]:
P    1.0
Q    1.0
R    2.0
S    2.0
T    3.0
U    3.0
dtype: float64
In [77]:
# Nan degerleri bir onceki deger ile degistir
veri.fillna(method='bfill')
Out[77]:
P    1.0
Q    2.0
R    2.0
S    3.0
T    3.0
U    NaN
dtype: float64
In [78]:
ders2.fillna(0, axis=1)
Out[78]:
odev ogrno proje
0 56.0 08 70.0
1 72.0 16 43.0
2 60.0 32 57.0
3 84.0 74 71.0
4 0.0 18 37.0
5 65.0 24 0.0

Dosyalardan Veri Almak

Pandas modülünden tablo yapısındaki ascii (salt metin), sütunlardaki değerleri virgülle ayrılan (csv), yaygın sayfa programlarıyla oluşturulan pek çok formattaki dosyadan veri çekilip, üzerinde işlemler yapılabilir. Öncelikle sütunlardaki değerleri virgülle ayrılmış bir tablo yapısı (csv) üzerinde bir örnekle çalışalım. ders_notlar.csv dosyasında bir derste öğrencilerin aldığı notlar (iki ödev, bir arasınav ve bir final olmak üzere) verilmiştir. Öncelikle bu dosyadaki veriyi alıp, bir veri çerçevesine aktaralım. Sonrasında buradaki verinin üzerinde işlemler yapabilir ve analiz edebiliriz.

Pandas modülünün csv fonksiyonu metin değişkenlere aktarılan sütun değerlerinin başında boşluk varsa (whitespace) bunları da metne dahil ettiğinden bu davranışı değiştirmek üzere skipinitialspace parametresi True değerine ayarlanmalıdır.

In [79]:
import pandas as pd
notlar = pd.read_csv('ders_notlar.csv', index_col="ad", skipinitialspace=True)
notlar
Out[79]:
odev1 odev2 arasinav final durum
ad
ogrenci1 100 0 NaN NaN W
ogrenci2 80 92 64.0 78.0 NaN
ogrenci3 95 100 71.0 88.0 NaN
ogrenci4 100 100 54.0 40.0 NaN
ogrenci5 97 0 NaN NaN W
ogrenci6 100 100 55.0 66.0 NaN
ogrenci7 100 100 91.0 87.0 NaN
ogrenci8 97 100 86.0 78.0 NaN
ogrenci9 75 0 68.0 NaN W
ogrenci10 95 0 85.0 NaN W
ogrenci11 100 100 75.0 76.0 NaN
ogrenci12 90 100 75.0 92.0 NaN
ogrenci13 95 100 72.0 77.0 NaN
ogrenci14 95 100 50.0 44.0 NaN
ogrenci15 100 100 91.0 98.0 NaN
ogrenci16 90 100 75.0 86.0 NaN
ogrenci17 95 100 63.0 67.0 NaN
ogrenci18 100 100 88.0 96.0 NaN
ogrenci19 70 98 59.0 76.0 NaN
ogrenci20 100 100 81.0 94.0 NaN
ogrenci21 95 97 75.0 83.0 NaN
ogrenci22 100 100 85.0 100.0 NaN
ogrenci23 90 100 79.0 70.0 NaN
ogrenci24 90 0 NaN NaN W
ogrenci25 0 75 50.0 74.0 NaN
ogrenci26 100 100 68.0 75.0 NaN
ogrenci27 92 97 63.0 59.0 NaN
ogrenci28 100 100 81.0 76.0 NaN
ogrenci29 100 97 52.0 69.0 NaN
ogrenci30 92 0 86.0 NaN W
ogrenci31 87 100 59.0 82.0 NaN
ogrenci32 100 100 92.0 89.0 NaN
ogrenci33 100 100 92.0 100.0 NaN
ogrenci34 95 100 53.0 69.0 NaN
ogrenci35 100 100 94.0 83.0 NaN
ogrenci36 95 0 76.0 79.0 NaN
ogrenci37 78 0 47.0 23.0 NaN

Eğer ders_notlar.csv dosyasını bir metin editörle açacak olursanız hem NaN olarak girilen değerler (sınava girmeyenler için), hem de boş bırakılan değerler (durum sütununda henüz durumu belirlenmemiş öğrenciler; W: dersten çekilenleri göstermektedir) göreceksiniz. Pandas boş bırakılan değerleri de NaN olarak yorumlamaktadır. Tüm sütun isimleri veri dosyasından çekilirken ad sütunu indeks olarak işaretlenmiştir. Başlığı olmayan ya da atlanmak istenen veri dosyaları için csv fonksiyonunun header parametresinde çeşitli seçenekler tanımlanmıştır.

In [80]:
# indekslenen sutun
print(notlar.index)
print("-----------------")
# tüm sutunlar
print(notlar.columns)
print("-----------------")
# Herhangi bir ogrencinin butun notlari
print(notlar.loc['ogrenci28'])
print("-----------------")
# Tum arasinav notlari
print(notlar['arasinav'])
Index(['ogrenci1', 'ogrenci2', 'ogrenci3', 'ogrenci4', 'ogrenci5', 'ogrenci6',
       'ogrenci7', 'ogrenci8', 'ogrenci9', 'ogrenci10', 'ogrenci11',
       'ogrenci12', 'ogrenci13', 'ogrenci14', 'ogrenci15', 'ogrenci16',
       'ogrenci17', 'ogrenci18', 'ogrenci19', 'ogrenci20', 'ogrenci21',
       'ogrenci22', 'ogrenci23', 'ogrenci24', 'ogrenci25', 'ogrenci26',
       'ogrenci27', 'ogrenci28', 'ogrenci29', 'ogrenci30', 'ogrenci31',
       'ogrenci32', 'ogrenci33', 'ogrenci34', 'ogrenci35', 'ogrenci36',
       'ogrenci37'],
      dtype='object', name='ad')
-----------------
Index(['odev1', 'odev2', 'arasinav', 'final', 'durum'], dtype='object')
-----------------
odev1       100
odev2       100
arasinav     81
final        76
durum       NaN
Name: ogrenci28, dtype: object
-----------------
ad
ogrenci1      NaN
ogrenci2     64.0
ogrenci3     71.0
ogrenci4     54.0
ogrenci5      NaN
ogrenci6     55.0
ogrenci7     91.0
ogrenci8     86.0
ogrenci9     68.0
ogrenci10    85.0
ogrenci11    75.0
ogrenci12    75.0
ogrenci13    72.0
ogrenci14    50.0
ogrenci15    91.0
ogrenci16    75.0
ogrenci17    63.0
ogrenci18    88.0
ogrenci19    59.0
ogrenci20    81.0
ogrenci21    75.0
ogrenci22    85.0
ogrenci23    79.0
ogrenci24     NaN
ogrenci25    50.0
ogrenci26    68.0
ogrenci27    63.0
ogrenci28    81.0
ogrenci29    52.0
ogrenci30    86.0
ogrenci31    59.0
ogrenci32    92.0
ogrenci33    92.0
ogrenci34    53.0
ogrenci35    94.0
ogrenci36    76.0
ogrenci37    47.0
Name: arasinav, dtype: float64

Şimdi bir analiz işlemi yapabiliriz. Örneğin aldığı tüm notlardan öğrencinin ağırlıklı genel ortalamasını çıkarabiliriz. Bu ders için her iki ödevin %10'ar (toplamda %20), arasınavın %30, finalin ise %50 ağırlığının olduğunu varsayalım

In [81]:
notlar['genel_ortalama'] = notlar['odev1']*0.1 + notlar['odev2']*0.1 + notlar['arasinav']*0.3 + notlar['final']*0.5
notlar['genel_ortalama']
Out[81]:
ad
ogrenci1      NaN
ogrenci2     75.4
ogrenci3     84.8
ogrenci4     56.2
ogrenci5      NaN
ogrenci6     69.5
ogrenci7     90.8
ogrenci8     84.5
ogrenci9      NaN
ogrenci10     NaN
ogrenci11    80.5
ogrenci12    87.5
ogrenci13    79.6
ogrenci14    56.5
ogrenci15    96.3
ogrenci16    84.5
ogrenci17    71.9
ogrenci18    94.4
ogrenci19    72.5
ogrenci20    91.3
ogrenci21    83.2
ogrenci22    95.5
ogrenci23    77.7
ogrenci24     NaN
ogrenci25    59.5
ogrenci26    77.9
ogrenci27    67.3
ogrenci28    82.3
ogrenci29    69.8
ogrenci30     NaN
ogrenci31    77.4
ogrenci32    92.1
ogrenci33    97.6
ogrenci34    69.9
ogrenci35    89.7
ogrenci36    71.8
ogrenci37    33.4
Name: genel_ortalama, dtype: float64

Bu ortalamalar hesaplanırken önemli bir şansımız arasınava girmeyen tüm öğrencilerin finale de girmemiş olması ve finale girmeyen tüm öğrencilerin de dersten çekilmiş (durum: W) olmalarıdır. Durumun bu olması zorunlu değildir. Örneğin bir öğrenci arasınava girmeyip derse devam etmiş, finale girmiş olabilir. Bu durumda arasınav notunu 0 yapmak gerekir. Bu tür ayarlamalar koşul yapılarıyla (if - elif - else) kontrol edilebilir. Ayrıca pandas bu tür kontroller için pratik fonksiyonlar da sağlamaktadır. Örneğin her öğrenci için ağırlıklı ortalama çıkarmak bakımından arasınav ve finale girmeyenlerin notlarını 0 varsaymak iyi bir fikir olacaktır. Öğrencinin dersten çekilip çekilmediği durum sütununda kontrol edilebildiği için (W) bu önemli bir avantaj sağlayacaktır. Bu amaçla veri çerçeveleri üzerine tanımlı fillna metodu kullanılabilir.

In [82]:
notlar = notlar.fillna(0)
notlar['genel_ortalama'] = notlar['odev1']*0.1 + notlar['odev2']*0.1 + notlar['arasinav']*0.3 + notlar['final']*0.5
notlar
Out[82]:
odev1 odev2 arasinav final durum genel_ortalama
ad
ogrenci1 100 0 0.0 0.0 W 10.0
ogrenci2 80 92 64.0 78.0 0 75.4
ogrenci3 95 100 71.0 88.0 0 84.8
ogrenci4 100 100 54.0 40.0 0 56.2
ogrenci5 97 0 0.0 0.0 W 9.7
ogrenci6 100 100 55.0 66.0 0 69.5
ogrenci7 100 100 91.0 87.0 0 90.8
ogrenci8 97 100 86.0 78.0 0 84.5
ogrenci9 75 0 68.0 0.0 W 27.9
ogrenci10 95 0 85.0 0.0 W 35.0
ogrenci11 100 100 75.0 76.0 0 80.5
ogrenci12 90 100 75.0 92.0 0 87.5
ogrenci13 95 100 72.0 77.0 0 79.6
ogrenci14 95 100 50.0 44.0 0 56.5
ogrenci15 100 100 91.0 98.0 0 96.3
ogrenci16 90 100 75.0 86.0 0 84.5
ogrenci17 95 100 63.0 67.0 0 71.9
ogrenci18 100 100 88.0 96.0 0 94.4
ogrenci19 70 98 59.0 76.0 0 72.5
ogrenci20 100 100 81.0 94.0 0 91.3
ogrenci21 95 97 75.0 83.0 0 83.2
ogrenci22 100 100 85.0 100.0 0 95.5
ogrenci23 90 100 79.0 70.0 0 77.7
ogrenci24 90 0 0.0 0.0 W 9.0
ogrenci25 0 75 50.0 74.0 0 59.5
ogrenci26 100 100 68.0 75.0 0 77.9
ogrenci27 92 97 63.0 59.0 0 67.3
ogrenci28 100 100 81.0 76.0 0 82.3
ogrenci29 100 97 52.0 69.0 0 69.8
ogrenci30 92 0 86.0 0.0 W 35.0
ogrenci31 87 100 59.0 82.0 0 77.4
ogrenci32 100 100 92.0 89.0 0 92.1
ogrenci33 100 100 92.0 100.0 0 97.6
ogrenci34 95 100 53.0 69.0 0 69.9
ogrenci35 100 100 94.0 83.0 0 89.7
ogrenci36 95 0 76.0 79.0 0 71.8
ogrenci37 78 0 47.0 23.0 0 33.4

Bu durumda durum sütununda da W olmayan satırlar 0 ile doldurulmuştur. Ayrıca arasınav ya da finale girmeyen öğrencilerin genel ortalaması NaN olarak belirlenmiş olduğu için onlar da 0'a dönüştürülmüştür. Bu nedenle genel_ortalama sütununu tekrar hesaplamakta yarar görülmüştür. Şimdi, durum sütunu ortalama notlarına bağlı olarak verilecek olan harf notları ile güncellenebilir.

In [83]:
ogrenciler = notlar.index.values
print(ogrenciler)
for i, ortalama in enumerate(notlar['genel_ortalama']):
    if ortalama > 89.500:
        notlar.at[ogrenciler[i], 'durum'] = 'A'
notlar
['ogrenci1' 'ogrenci2' 'ogrenci3' 'ogrenci4' 'ogrenci5' 'ogrenci6'
 'ogrenci7' 'ogrenci8' 'ogrenci9' 'ogrenci10' 'ogrenci11' 'ogrenci12'
 'ogrenci13' 'ogrenci14' 'ogrenci15' 'ogrenci16' 'ogrenci17' 'ogrenci18'
 'ogrenci19' 'ogrenci20' 'ogrenci21' 'ogrenci22' 'ogrenci23' 'ogrenci24'
 'ogrenci25' 'ogrenci26' 'ogrenci27' 'ogrenci28' 'ogrenci29' 'ogrenci30'
 'ogrenci31' 'ogrenci32' 'ogrenci33' 'ogrenci34' 'ogrenci35' 'ogrenci36'
 'ogrenci37']
Out[83]:
odev1 odev2 arasinav final durum genel_ortalama
ad
ogrenci1 100 0 0.0 0.0 W 10.0
ogrenci2 80 92 64.0 78.0 0 75.4
ogrenci3 95 100 71.0 88.0 0 84.8
ogrenci4 100 100 54.0 40.0 0 56.2
ogrenci5 97 0 0.0 0.0 W 9.7
ogrenci6 100 100 55.0 66.0 0 69.5
ogrenci7 100 100 91.0 87.0 A 90.8
ogrenci8 97 100 86.0 78.0 0 84.5
ogrenci9 75 0 68.0 0.0 W 27.9
ogrenci10 95 0 85.0 0.0 W 35.0
ogrenci11 100 100 75.0 76.0 0 80.5
ogrenci12 90 100 75.0 92.0 0 87.5
ogrenci13 95 100 72.0 77.0 0 79.6
ogrenci14 95 100 50.0 44.0 0 56.5
ogrenci15 100 100 91.0 98.0 A 96.3
ogrenci16 90 100 75.0 86.0 0 84.5
ogrenci17 95 100 63.0 67.0 0 71.9
ogrenci18 100 100 88.0 96.0 A 94.4
ogrenci19 70 98 59.0 76.0 0 72.5
ogrenci20 100 100 81.0 94.0 A 91.3
ogrenci21 95 97 75.0 83.0 0 83.2
ogrenci22 100 100 85.0 100.0 A 95.5
ogrenci23 90 100 79.0 70.0 0 77.7
ogrenci24 90 0 0.0 0.0 W 9.0
ogrenci25 0 75 50.0 74.0 0 59.5
ogrenci26 100 100 68.0 75.0 0 77.9
ogrenci27 92 97 63.0 59.0 0 67.3
ogrenci28 100 100 81.0 76.0 0 82.3
ogrenci29 100 97 52.0 69.0 0 69.8
ogrenci30 92 0 86.0 0.0 W 35.0
ogrenci31 87 100 59.0 82.0 0 77.4
ogrenci32 100 100 92.0 89.0 A 92.1
ogrenci33 100 100 92.0 100.0 A 97.6
ogrenci34 95 100 53.0 69.0 0 69.9
ogrenci35 100 100 94.0 83.0 A 89.7
ogrenci36 95 0 76.0 79.0 0 71.8
ogrenci37 78 0 47.0 23.0 0 33.4

Aynı sonucu dilimleme için koşul kullanmak suretiyle de almak mümkündür. Veri çerçeveleri üzerinde tanımlı loc metodu herhangi bir veya birden fazla sütunda istenen koşulu sağlayan satırları seçmek için kullanılablir. Bu satırlar seçildikten sonra bu koşulların sağlandığı satırda yer alan istenen sütun(lar) yeni değerleri ile güncellenebilir. Bu noktada birden fazla koşulun and ya da or gibi bir bağlaçla bağlanarak kombine koşullar oluşturulması mümkün olmakla birlikte pandas'ın and ve or yerine bitwise boolean operatörlerini ( & ve |) kullanıyor olmasına dikkat etmek gerekir.

In [84]:
notlar.loc[(notlar['genel_ortalama'] >= 87.500) & (notlar['genel_ortalama'] < 89.500), ['durum']] = 'A-'
notlar.loc[(notlar['genel_ortalama'] >= 84.000) & (notlar['genel_ortalama'] < 87.500), ['durum']] = 'B+'
notlar.loc[(notlar['genel_ortalama'] >= 79.500) & (notlar['genel_ortalama'] < 84.500), ['durum']] = 'B'
notlar.loc[(notlar['genel_ortalama'] >= 76.500) & (notlar['genel_ortalama'] < 79.500), ['durum']] = 'B-'
notlar.loc[(notlar['genel_ortalama'] >= 72.500) & (notlar['genel_ortalama'] < 76.500), ['durum']] = 'C+'
notlar.loc[(notlar['genel_ortalama'] >= 69.500) & (notlar['genel_ortalama'] < 72.500), ['durum']] = 'C'
notlar.loc[(notlar['genel_ortalama'] >= 64.500) & (notlar['genel_ortalama'] < 69.500), ['durum']] = 'C-'
notlar.loc[(notlar['genel_ortalama'] >= 59.500) & (notlar['genel_ortalama'] < 64.500), ['durum']] = 'D+'
notlar.loc[(notlar['genel_ortalama'] >= 54.500) & (notlar['genel_ortalama'] < 59.500), ['durum']] = 'D'
notlar.loc[(notlar['genel_ortalama'] < 54.500) & (notlar['durum'] != 'W'), ['durum']] = 'F'
In [85]:
notlar
Out[85]:
odev1 odev2 arasinav final durum genel_ortalama
ad
ogrenci1 100 0 0.0 0.0 W 10.0
ogrenci2 80 92 64.0 78.0 C+ 75.4
ogrenci3 95 100 71.0 88.0 B+ 84.8
ogrenci4 100 100 54.0 40.0 D 56.2
ogrenci5 97 0 0.0 0.0 W 9.7
ogrenci6 100 100 55.0 66.0 C 69.5
ogrenci7 100 100 91.0 87.0 A 90.8
ogrenci8 97 100 86.0 78.0 B+ 84.5
ogrenci9 75 0 68.0 0.0 W 27.9
ogrenci10 95 0 85.0 0.0 W 35.0
ogrenci11 100 100 75.0 76.0 B 80.5
ogrenci12 90 100 75.0 92.0 A- 87.5
ogrenci13 95 100 72.0 77.0 B 79.6
ogrenci14 95 100 50.0 44.0 D 56.5
ogrenci15 100 100 91.0 98.0 A 96.3
ogrenci16 90 100 75.0 86.0 B+ 84.5
ogrenci17 95 100 63.0 67.0 C 71.9
ogrenci18 100 100 88.0 96.0 A 94.4
ogrenci19 70 98 59.0 76.0 C+ 72.5
ogrenci20 100 100 81.0 94.0 A 91.3
ogrenci21 95 97 75.0 83.0 B 83.2
ogrenci22 100 100 85.0 100.0 A 95.5
ogrenci23 90 100 79.0 70.0 B- 77.7
ogrenci24 90 0 0.0 0.0 W 9.0
ogrenci25 0 75 50.0 74.0 D+ 59.5
ogrenci26 100 100 68.0 75.0 B- 77.9
ogrenci27 92 97 63.0 59.0 C- 67.3
ogrenci28 100 100 81.0 76.0 B 82.3
ogrenci29 100 97 52.0 69.0 C 69.8
ogrenci30 92 0 86.0 0.0 W 35.0
ogrenci31 87 100 59.0 82.0 B- 77.4
ogrenci32 100 100 92.0 89.0 A 92.1
ogrenci33 100 100 92.0 100.0 A 97.6
ogrenci34 95 100 53.0 69.0 C 69.9
ogrenci35 100 100 94.0 83.0 A 89.7
ogrenci36 95 0 76.0 79.0 C 71.8
ogrenci37 78 0 47.0 23.0 F 33.4

pandas'ın istatistiki analize yönelik pek çok fonksiyonu bulunmaktadır. Bunlardan bazılarını örnekleyelim.

In [86]:
notlar.describe()
Out[86]:
odev1 odev2 arasinav final genel_ortalama
count 37.000000 37.000000 37.000000 37.000000 37.000000
mean 91.567568 77.189189 66.351351 64.162162 68.862162
std 17.234559 41.321126 24.261556 32.707044 25.339926
min 0.000000 0.000000 0.000000 0.000000 9.000000
25% 90.000000 92.000000 55.000000 59.000000 59.500000
50% 95.000000 100.000000 72.000000 76.000000 77.400000
75% 100.000000 100.000000 85.000000 86.000000 84.800000
max 100.000000 100.000000 94.000000 100.000000 97.600000
In [87]:
notlar.sort_values(by="final")
Out[87]:
odev1 odev2 arasinav final durum genel_ortalama
ad
ogrenci1 100 0 0.0 0.0 W 10.0
ogrenci30 92 0 86.0 0.0 W 35.0
ogrenci24 90 0 0.0 0.0 W 9.0
ogrenci10 95 0 85.0 0.0 W 35.0
ogrenci5 97 0 0.0 0.0 W 9.7
ogrenci9 75 0 68.0 0.0 W 27.9
ogrenci37 78 0 47.0 23.0 F 33.4
ogrenci4 100 100 54.0 40.0 D 56.2
ogrenci14 95 100 50.0 44.0 D 56.5
ogrenci27 92 97 63.0 59.0 C- 67.3
ogrenci6 100 100 55.0 66.0 C 69.5
ogrenci17 95 100 63.0 67.0 C 71.9
ogrenci34 95 100 53.0 69.0 C 69.9
ogrenci29 100 97 52.0 69.0 C 69.8
ogrenci23 90 100 79.0 70.0 B- 77.7
ogrenci25 0 75 50.0 74.0 D+ 59.5
ogrenci26 100 100 68.0 75.0 B- 77.9
ogrenci19 70 98 59.0 76.0 C+ 72.5
ogrenci11 100 100 75.0 76.0 B 80.5
ogrenci28 100 100 81.0 76.0 B 82.3
ogrenci13 95 100 72.0 77.0 B 79.6
ogrenci2 80 92 64.0 78.0 C+ 75.4
ogrenci8 97 100 86.0 78.0 B+ 84.5
ogrenci36 95 0 76.0 79.0 C 71.8
ogrenci31 87 100 59.0 82.0 B- 77.4
ogrenci21 95 97 75.0 83.0 B 83.2
ogrenci35 100 100 94.0 83.0 A 89.7
ogrenci16 90 100 75.0 86.0 B+ 84.5
ogrenci7 100 100 91.0 87.0 A 90.8
ogrenci3 95 100 71.0 88.0 B+ 84.8
ogrenci32 100 100 92.0 89.0 A 92.1
ogrenci12 90 100 75.0 92.0 A- 87.5
ogrenci20 100 100 81.0 94.0 A 91.3
ogrenci18 100 100 88.0 96.0 A 94.4
ogrenci15 100 100 91.0 98.0 A 96.3
ogrenci33 100 100 92.0 100.0 A 97.6
ogrenci22 100 100 85.0 100.0 A 95.5
In [88]:
notlar.mean()
Out[88]:
odev1             91.567568
odev2             77.189189
arasinav          66.351351
final             64.162162
genel_ortalama    68.862162
dtype: float64
In [89]:
notlar.median()
Out[89]:
odev1              95.0
odev2             100.0
arasinav           72.0
final              76.0
genel_ortalama     77.4
dtype: float64
In [90]:
notlar.max()
Out[90]:
odev1              100
odev2              100
arasinav            94
final              100
durum                W
genel_ortalama    97.6
dtype: object

Biraz da analiz yapmak üzere derste alınan notları inceleyelim.

In [91]:
notlar["durum"].value_counts()
Out[91]:
A     8
W     6
C     5
B     4
B-    3
B+    3
C+    2
D     2
C-    1
A-    1
F     1
D+    1
Name: durum, dtype: int64

Bu veriçerçevesi kategorik veri taşıdığı için doğrudan hist fonksiyonunu kullanamasak da bir histogram görmek için plot fonksiyonunun bar seçeneğini kullanabiliriz.

In [92]:
notlar['durum'].value_counts().plot(kind='bar')
Out[92]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f1ee3dccc50>

Veri çerçevesi nesnelerinin üzerinde çizim fonksiyounu (plot) da tanımlıdır. Bunun için ayrıca matplotlib kütüphanesi çağırmaya gerek yoktur, çünkü çizim fonksiyonu matplotlib'i kendi çağırır.

In [93]:
%matplotlib inline
notlar['final'].plot()
Out[93]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f1ee1497e48>
In [94]:
notlar.plot.scatter(x="arasinav", y="final", marker="o")
Out[94]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f1ee1454ba8>

pandas veri çerçeveleri kolaylıkla $\LaTeX$ formatındaki tablolara dönüştürülüp, yayınlara aktarılabilir.

In [95]:
notlar_latex = notlar.to_latex()
print(notlar_latex)
\begin{tabular}{lrrrrlr}
\toprule
{} &  odev1 &  odev2 &  arasinav &  final & durum &  genel\_ortalama \\
ad        &        &        &           &        &       &                 \\
\midrule
ogrenci1  &    100 &      0 &       0.0 &    0.0 &     W &            10.0 \\
ogrenci2  &     80 &     92 &      64.0 &   78.0 &    C+ &            75.4 \\
ogrenci3  &     95 &    100 &      71.0 &   88.0 &    B+ &            84.8 \\
ogrenci4  &    100 &    100 &      54.0 &   40.0 &     D &            56.2 \\
ogrenci5  &     97 &      0 &       0.0 &    0.0 &     W &             9.7 \\
ogrenci6  &    100 &    100 &      55.0 &   66.0 &     C &            69.5 \\
ogrenci7  &    100 &    100 &      91.0 &   87.0 &     A &            90.8 \\
ogrenci8  &     97 &    100 &      86.0 &   78.0 &    B+ &            84.5 \\
ogrenci9  &     75 &      0 &      68.0 &    0.0 &     W &            27.9 \\
ogrenci10 &     95 &      0 &      85.0 &    0.0 &     W &            35.0 \\
ogrenci11 &    100 &    100 &      75.0 &   76.0 &     B &            80.5 \\
ogrenci12 &     90 &    100 &      75.0 &   92.0 &    A- &            87.5 \\
ogrenci13 &     95 &    100 &      72.0 &   77.0 &     B &            79.6 \\
ogrenci14 &     95 &    100 &      50.0 &   44.0 &     D &            56.5 \\
ogrenci15 &    100 &    100 &      91.0 &   98.0 &     A &            96.3 \\
ogrenci16 &     90 &    100 &      75.0 &   86.0 &    B+ &            84.5 \\
ogrenci17 &     95 &    100 &      63.0 &   67.0 &     C &            71.9 \\
ogrenci18 &    100 &    100 &      88.0 &   96.0 &     A &            94.4 \\
ogrenci19 &     70 &     98 &      59.0 &   76.0 &    C+ &            72.5 \\
ogrenci20 &    100 &    100 &      81.0 &   94.0 &     A &            91.3 \\
ogrenci21 &     95 &     97 &      75.0 &   83.0 &     B &            83.2 \\
ogrenci22 &    100 &    100 &      85.0 &  100.0 &     A &            95.5 \\
ogrenci23 &     90 &    100 &      79.0 &   70.0 &    B- &            77.7 \\
ogrenci24 &     90 &      0 &       0.0 &    0.0 &     W &             9.0 \\
ogrenci25 &      0 &     75 &      50.0 &   74.0 &    D+ &            59.5 \\
ogrenci26 &    100 &    100 &      68.0 &   75.0 &    B- &            77.9 \\
ogrenci27 &     92 &     97 &      63.0 &   59.0 &    C- &            67.3 \\
ogrenci28 &    100 &    100 &      81.0 &   76.0 &     B &            82.3 \\
ogrenci29 &    100 &     97 &      52.0 &   69.0 &     C &            69.8 \\
ogrenci30 &     92 &      0 &      86.0 &    0.0 &     W &            35.0 \\
ogrenci31 &     87 &    100 &      59.0 &   82.0 &    B- &            77.4 \\
ogrenci32 &    100 &    100 &      92.0 &   89.0 &     A &            92.1 \\
ogrenci33 &    100 &    100 &      92.0 &  100.0 &     A &            97.6 \\
ogrenci34 &     95 &    100 &      53.0 &   69.0 &     C &            69.9 \\
ogrenci35 &    100 &    100 &      94.0 &   83.0 &     A &            89.7 \\
ogrenci36 &     95 &      0 &      76.0 &   79.0 &     C &            71.8 \\
ogrenci37 &     78 &      0 &      47.0 &   23.0 &     F &            33.4 \\
\bottomrule
\end{tabular}

Sonuç olarak oluşan notlar veriçerçevesini yine virgülle ayrılmış bir salt metin dosyasına (ders_notlar_sonuc.csv) adıyla yazdıralım.

In [96]:
notlar.to_csv("ders_notlar_sonuc.csv")

Ödev 2

Teslim Tarihi: 11 Mart 2020, Çarşamba 09:30

exoplanet.eu kataloğunu ödev teslim tarihine kadar herhahgi bir zamanda bilgisayarınıza indirdikten sonra bir pandas veri çerçevesi nesnesine alınız.

  1. Kataloğun ilk 10 ve son 10 satırını ekrana yazdırınız.

  2. Kataloğun tüm sütunları için en temel istatistikleri ekrana yazdırınız.

  3. Kataloğu sadece size verilen gezegen türü için sınırlandırınız.

  4. Söz konusu gezegen türü için kütle ve yarıçapı belirlenmiş olanların yoğunluklarını hesaplayarak, barınak yıldızın metal bolluğuna karşı çizdiriniz. Grafiğinizdeki aykırı noktaları belirleyerek çıkarınız. Grafiği çizdirmeden önce nasıl bir ilişki görmeyi beklerdiniz? Beklentiniz ile çizdirdiğiniz grafiği karşılaştırarak yorumlayınız.

  5. Üzerinde çalıştığınız gezegenlerin barınak yıldızlarının sıcaklıklarının, metal bolluklarının, kütlelerinin, yarıçaplarının ve yaşlarının temel istatistiklerini ekrana yazdırınız.

  6. Bir önceki soruda verilen parametrelerin aykırı noktalarını göstermek üzere kutu grafiklerini çizdiriniz.

  7. Kutu grafiği temelinde aykırı noktalarından ayıkladığınız parametrelerin histogramlarını çizdiriniz.

  8. Üzerinde çalıştığınız gezegen grubu için kütle ve yarıçap ilişkisini bir grafik üzerinde gösteriniz.

Gezegen grupları:

Sıcak Jüpiterler: Kütleleri $0.36 M_{jüp}$'den büyük, yörünge dönemleri $1.3 – 10$ Dünya günü arasında değişen gezegenler: Şeyma Torun

Ilık Jüpiterler: Kütleleri $0.36 M_{jüp}$'den büyük, yörünge dönemleri $10 – 100$ Dünya günü arasında değişen gezegenler: Meltem Yıldız

Satürnler: Kütleleri $0.30 M_{jüp}$'den, yyğunlukları $0.8 g/cm^3$ 'ten küçük gezegenler: Javid Bashirzade

Süper DünyalarKütleleri $2.0 M_{yer}$ ile $10.0 M_{yer}$, yarıçapları $0.8 R_{yer}$ ile $1.25 R_yer$ arasında değişen gezegenler: Uğur Şenaslan

Mini-neptünlerKütleleri $6.0 M_{yer}$ ile $12.0 M_{yer}$, yarıçapları $1.6 R_{yer}$ ile $2.00 R_yer$ arasında değişen gezegenler: Furkan Tomak

Soğuk Jüpiterler: Kütleleri $0.36 M_{jüp}$'den, yörünge dönemleri $100$ Dünya gününden büyük gezegenler: Ekrem Murat Esmer

Kaynaklar