800100715151 Astronomide Veritabanları

Ders - 04a Pandas Paketiyle Veri İşleme Uygulaması

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 Paketi İleri Konular Uygulama

Ders-4a: Ötegezegen Veritabanları Uygulaması

Ötegezegenler ve onların barınak yıldızlarına ilişkin pek çok parametrenin bulunduğu ötegezegen veritabanları arasında öne çıkan iki tanesi NASA Exoplanet Archive tarafından sağlanan veritabanı ile Cenevre Üniversitesi'nde tutulan exoplanet.eu veritabanıdır. İki veritabanında da benzer veriler yer aldığı gibi bir veritabanında olup diğerinde olmayan (barınak yıldız metal bolluğu gibi) ya da farklı kaynaklardan alınan veriler de bulunmaktadır. Bu iki veritabanını pandas paketinin sağladığı olanaklarla çeşitli şekillerde birleştirerek sorgulayabiliriz.

Öncelikle her iki tabloyu astroquery fonksiyonlarıyla sorgulayarak birer pandas veriçerçevesine alalım. NASA Exoplanet Archive ötegezegenler ve gözlemleriyle ilgili pek çok tablo ve veri sunmaktadır. Bu veri tablolarından ikisi tüm ötegezegen, sistem ve barınak yıldız parametrelerinin farklı literatür kaynaklarından alınarak listelendiği Planetary Systems, diğeri bu parametrelerin farklı kaynaklardan derlenerek her bir gezegen için tek bir satır halinde sunulduğu Planetary Systems Composite Data tablosudur. Bu tablolara astroquery modüllerinden NasaExoplanetArchive NASA Exoplanet Archive veritabanını kritere göre tarayan fonksiyonu query_criteria ile erişilebilir. Tüm literatür kaynaklarından alınan verilerin sunulduğu tablo ps, parametrelerin derlenerek tek bir satıra dönüştürüldüğü tablo pscommpars adıyla table anahtarına sağlanmalı; tüm tablo çekilmek isteniyorsa, SQL sorgu nesnesinin sağlandığı select parametresi " * " değerine atanmalıdır.

In [1]:
#from astroquery.ipac.nexsci.nasa_exoplanet_archive import NasaExoplanetArchive
import pandas as pd
In [2]:
#nasatablo = NasaExoplanetArchive.query_criteria(table="pscomppars", select="*")
In [3]:
#nasatablo.columns
In [4]:
#nasaexo = nasatablo.to_pandas()

exoplanet.eu veritabanına bağlanmak için bir astroquery servisi tanımlanmadığından bu veritabanını sorgulayabilmek ya da çevrimiçi çekip kullanabilmek için ya requests modülü fonksiyonlarını kullanmak ya da sitenilen formatta (Virtual Observatory --VO-- tablosu, csv, dat) indirip uygun pandas fonksiyonuyla açmak gerekecektir. DACE platformunun bir parçası olan katalog, Sanal Gözlemevi standardı Tablo Erişim Protokolü (Table Access Protocol, TAP) fonksiyonları ile sorgulamaya açıktır ve pyvo modülü fonksiyonlarıyla sorgulanabilir ve tıpkı NASA Exoplanet Archive veritabanı gibi kullanılabilir.

In [5]:
nasaexo = pd.read_csv('veri/PSCompPars_2024.04.02_02.08.30.csv',
                     comment="#", skipinitialspace=True)
exoeu = pd.read_csv('veri/exoplanet.eu_catalog_20240402.csv',  
                    skipinitialspace=True)

print("NASA Exooplanet Archive veritabani sutunlari")
print("-"*45)
print(nasaexo.columns)
print("x"*80)
print("exoplanet.eu veritabani sutunlari")
print("-"*45)
print(exoeu.columns)
NASA Exooplanet Archive veritabani sutunlari
---------------------------------------------
Index(['pl_name', 'hostname', 'sy_snum', 'sy_pnum', 'discoverymethod',
       'disc_year', 'disc_facility', 'pl_controv_flag', 'pl_orbper',
       'pl_orbpererr1', 'pl_orbpererr2', 'pl_orbperlim', 'pl_orbsmax',
       'pl_orbsmaxerr1', 'pl_orbsmaxerr2', 'pl_orbsmaxlim', 'pl_rade',
       'pl_radeerr1', 'pl_radeerr2', 'pl_radelim', 'pl_radj', 'pl_radjerr1',
       'pl_radjerr2', 'pl_radjlim', 'pl_bmasse', 'pl_bmasseerr1',
       'pl_bmasseerr2', 'pl_bmasselim', 'pl_bmassj', 'pl_bmassjerr1',
       'pl_bmassjerr2', 'pl_bmassjlim', 'pl_bmassprov', 'pl_orbeccen',
       'pl_orbeccenerr1', 'pl_orbeccenerr2', 'pl_orbeccenlim', 'pl_insol',
       'pl_insolerr1', 'pl_insolerr2', 'pl_insollim', 'pl_eqt', 'pl_eqterr1',
       'pl_eqterr2', 'pl_eqtlim', 'ttv_flag', 'st_spectype', 'st_teff',
       'st_tefferr1', 'st_tefferr2', 'st_tefflim', 'st_rad', 'st_raderr1',
       'st_raderr2', 'st_radlim', 'st_mass', 'st_masserr1', 'st_masserr2',
       'st_masslim', 'st_met', 'st_meterr1', 'st_meterr2', 'st_metlim',
       'st_metratio', 'st_logg', 'st_loggerr1', 'st_loggerr2', 'st_logglim',
       'rastr', 'ra', 'decstr', 'dec', 'sy_dist', 'sy_disterr1', 'sy_disterr2',
       'sy_vmag', 'sy_vmagerr1', 'sy_vmagerr2', 'sy_kmag', 'sy_kmagerr1',
       'sy_kmagerr2', 'sy_gaiamag', 'sy_gaiamagerr1', 'sy_gaiamagerr2'],
      dtype='object')
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
exoplanet.eu veritabani sutunlari
---------------------------------------------
Index(['name', 'planet_status', 'mass', 'mass_error_min', 'mass_error_max',
       'mass_sini', 'mass_sini_error_min', 'mass_sini_error_max', 'radius',
       'radius_error_min', 'radius_error_max', 'orbital_period',
       'orbital_period_error_min', 'orbital_period_error_max',
       'semi_major_axis', 'semi_major_axis_error_min',
       'semi_major_axis_error_max', 'eccentricity', 'eccentricity_error_min',
       'eccentricity_error_max', 'inclination', 'inclination_error_min',
       'inclination_error_max', 'angular_distance', 'discovered', 'updated',
       'omega', 'omega_error_min', 'omega_error_max', 'tperi',
       'tperi_error_min', 'tperi_error_max', 'tconj', 'tconj_error_min',
       'tconj_error_max', 'tzero_tr', 'tzero_tr_error_min',
       'tzero_tr_error_max', 'tzero_tr_sec', 'tzero_tr_sec_error_min',
       'tzero_tr_sec_error_max', 'lambda_angle', 'lambda_angle_error_min',
       'lambda_angle_error_max', 'impact_parameter',
       'impact_parameter_error_min', 'impact_parameter_error_max', 'tzero_vr',
       'tzero_vr_error_min', 'tzero_vr_error_max', 'k', 'k_error_min',
       'k_error_max', 'temp_calculated', 'temp_calculated_error_min',
       'temp_calculated_error_max', 'temp_measured', 'hot_point_lon',
       'geometric_albedo', 'geometric_albedo_error_min',
       'geometric_albedo_error_max', 'log_g', 'publication', 'detection_type',
       'mass_detection_type', 'radius_detection_type', 'alternate_names',
       'molecules', 'star_name', 'ra', 'dec', 'mag_v', 'mag_i', 'mag_j',
       'mag_h', 'mag_k', 'star_distance', 'star_distance_error_min',
       'star_distance_error_max', 'star_metallicity',
       'star_metallicity_error_min', 'star_metallicity_error_max', 'star_mass',
       'star_mass_error_min', 'star_mass_error_max', 'star_radius',
       'star_radius_error_min', 'star_radius_error_max', 'star_sp_type',
       'star_age', 'star_age_error_min', 'star_age_error_max', 'star_teff',
       'star_teff_error_min', 'star_teff_error_max', 'star_detected_disc',
       'star_magnetic_field', 'star_alternate_names'],
      dtype='object')

Görüldüğü üzere farklı veritabanlarında aynı sütunlar farklı isimlerle bulunabilmektedir. Örneğin NASA Exoplanet Archive veritabanında pl_name sütununda yer alan gezegen isimleri # name sütununda yer almaktadır.

Başa Dön

Soru 1.

NASA Exoplanet Archive'dan bu uygulama için indirilen veritabanı gezegen doğaları başka gözlemlerle (örneğin hem geçiş, hem dikine hız) kesinleştirilmiş ve bu nedenle "onaylanmış" (ing. confirmed) ötegezegenleri içermektedir. exoplanet.eu veritabanında ise bu şekilde kesinleştirilmemiş gezegenler de bulunmaktadır. Her iki veritabanını bağlamak üzere gezegen isimlerini kullanınız ve bu iki veritabanında birden bulunan gezegenleri alınız. Gezegen ismini bu bağlanmış veritabanının indeksi haline getiriniz.

Çözüm 1.

pandas paketinin iki veriçerçevesindeki verileri bağlamak için kullandığı fonksiyon pd.merge() fonksiyonudur. Fonksiyon varsayılan olarak bizim de amaçladığımız kesişim işlemini how = "inner" parametresi ile sağlar. Ancak her iki verçerçevesinde gezegen isimlerinin bulunduğu sütunlar farklıdır. Bu sütunların fonksiyona veritabanlarının verildiği sırayla hangi isimlerde olduğu left_on ve right_on parametrelerine sağlanmalıdır. Sonrasında oluşacak yeni verçerçevesinin indeksini gezegen ismi yapmak üzere veriçerçeveleri üzerine tanımlı set_index metoduna pl_name sütun ismi sağlanarak istenen hedefe ulaşılabilir.

In [6]:
og = pd.merge(nasaexo, exoeu, how="inner",\
                          left_on="pl_name", right_on="name")
og.set_index("pl_name", inplace=True)
print("NASA Exoplanet Archive veritabani buyuklugu: ", nasaexo.shape)
print("exoplanet.eu veritabani buyuklugu: ", exoeu.shape)
print("İki veritabaninin kesisiminin buyuklugu: ", og.shape)
NASA Exoplanet Archive veritabani buyuklugu:  (5602, 84)
exoplanet.eu veritabani buyuklugu:  (5653, 98)
İki veritabaninin kesisiminin buyuklugu:  (4630, 181)
In [7]:
nasaexo[nasaexo['pl_name'] == 'Kepler-16 b']
Out[7]:
pl_name hostname sy_snum sy_pnum discoverymethod disc_year disc_facility pl_controv_flag pl_orbper pl_orbpererr1 ... sy_disterr2 sy_vmag sy_vmagerr1 sy_vmagerr2 sy_kmag sy_kmagerr1 sy_kmagerr2 sy_gaiamag sy_gaiamagerr1 sy_gaiamagerr2
2792 Kepler-16 b Kepler-16 2 1 Transit 2011 Kepler 0 228.776 0.02 ... -0.1536 12.144 0.057 -0.057 8.996 0.022 -0.022 11.7472 0.000348 -0.000348

1 rows × 84 columns

In [8]:
exoeu[exoeu['name'] == 'Kepler-16 b']
Out[8]:
name planet_status mass mass_error_min mass_error_max mass_sini mass_sini_error_min mass_sini_error_max radius radius_error_min ... star_sp_type star_age star_age_error_min star_age_error_max star_teff star_teff_error_min star_teff_error_max star_detected_disc star_magnetic_field star_alternate_names

0 rows × 98 columns

In [9]:
exoeu[exoeu['name'] == 'Kepler-16 (AB) b']
Out[9]:
name planet_status mass mass_error_min mass_error_max mass_sini mass_sini_error_min mass_sini_error_max radius radius_error_min ... star_sp_type star_age star_age_error_min star_age_error_max star_teff star_teff_error_min star_teff_error_max star_detected_disc star_magnetic_field star_alternate_names
2858 Kepler-16 (AB) b Confirmed 0.333 0.016 0.016 NaN NaN NaN 0.7538 0.0023 ... K NaN NaN NaN 4450.0 150.0 150.0 NaN NaN NaN

1 rows × 98 columns

Görüldüğü üzere her iki veritabanında sırasıylsa 5602 ve 5653 ötegezegen olmasına karşın, kesişimlerinde toplam 4630 ötegezegen bulunmaktadır. Aslında aynı isimle olmasa dahi her iki veritabanında yer alan bazı ötegezegenler maalesef bulunmaktadır. Bunun nedeni zaman zaman ortaya çıkan isim karışıklığıdır. Örneğin NASA Exoplanet Archive veritabanında Kepler-16 b ismiyle yer alan ötegezegen, exoplanet.eu veritabanında bir çift yıldızın etrafında dolanan bir gezegen olduğu (ing. circumbinary planet) için Kepler 16 (AB) b ismiyle yer almaktadır. Yukarıdaki gibi bir birleştirmeyle bu tür ötegezegenleri veritabanında kaybetme tehlikesi vardır. Maalesef bu özel durumdan kaçınmanın kolay bir yolu olmayabilir. Özelde çift yıldız gezegenlerinin isimlerini kontrol edip eşleştirebilecek $string$ fonksiyonlarından faydalanılabilir. Ancak amacımız bu olmadığı için bu hataları bu uygulamada görmezden geliyoruz. Çalışma alanında deneyimli ve bu veritabanları üzerinden bir bilimsel araştırma yürütecek bir araştırıcının bu tür durumları da dikkate alması ve bunlar için de fonksiyonlar yazması ve öncesinde üzerinde çalışacağı veritabanlarını iyice incelemesi gerekir.

Daha önemlisi birbirine bağlanan veritabanlarında sırasıyla 84 ve 98 sütun bulunduğu için bağlama işlemi sonunda oluşan $og$ veritabanında 181 sütunun bulunmasıdır. Bu durumda her iki veritabanında birden çok kez bulunan sütunların hangilerinin nihai veritabanında bulunup hangilerinin bulunmayacağına karar vermek gerek. Bu bilgiler, farklı veritabanlarında farklı kaynaklardan (literatür referanslarından) geliyor olabilir. Üzerinde çalışılacak birleştirilmiş veritabanının sağlıklı veriler içermesi için yapılması gereken bu seçimde öncelikler araştırmacıdan araştırmacıya, ya da yapılacak araştırmanın niteliğine göre değişebilir. Biz bu uygulamada her iki veritabanında da bulunan bilgiler için NASA Exoplanet Archive'da bulunanları kullanmayı tercih edeceğiz.

Soru 2.

Her iki veritabanında da bulunan sütunları belirleyerek bunlardan exoplanet.eu veritabanında bulunanları bağlanmış veriçerçevenizden atınız.

Çözüm 2.

Öncelikle her iki veritabanında aynı bilgiyi barındıran (aynı referanstan alınmayabildiği için bazıları tam olarak aynı olmayabilir ancak biz NASA Explanet Archive veritabanında bulunan bilgileri kullanmayı tercih ettik), ancak farklı isimle bulunan sütunların exoplanet.eu veritabanındaki isimlerini bir listeye toplayalım. Sonra bu listeyi pandas veriçerçevelerine uygulanan drop() fonksiyonuna sütun silecek şekilde axis parametresini $1$ değerine ayarlayarak atalım ve yaptığımız değişikliği kalıcı hale getirmek için inplace parametresini de $True$ değerine ayarlayalım.

In [10]:
atilacak_sutunlar = ['star_name','name','detection_type',
                 'orbital_period','orbital_period_error_min','orbital_period_error_max',
                 'semi_major_axis','semi_major_axis_error_min','semi_major_axis_error_max',
                 'eccentricity','eccentricity_error_min','eccentricity_error_max',
                 'inclination','inclination_error_min','inclination_error_max',
                 'mass','mass_error_min','mass_error_max','mass_detection_type',
                  'radius','radius_error_min','radius_error_max']
og.drop(atilacak_sutunlar,axis=1,inplace=True)
og.columns
Out[10]:
Index(['hostname', 'sy_snum', 'sy_pnum', 'discoverymethod', 'disc_year',
       'disc_facility', 'pl_controv_flag', 'pl_orbper', 'pl_orbpererr1',
       'pl_orbpererr2',
       ...
       'star_sp_type', 'star_age', 'star_age_error_min', 'star_age_error_max',
       'star_teff', 'star_teff_error_min', 'star_teff_error_max',
       'star_detected_disc', 'star_magnetic_field', 'star_alternate_names'],
      dtype='object', length=159)

Görüldüğü gibi her iki veriçerçevesinde de "aynı" bilgiyi içeren, ancak farklı isimle bulunan toplamda 22 sütunu attık ve sütun sayımız 159'a indi.

Soru 3.

Her iki veritabanında da aynı isimle bulunan ve barınak yıldızın ekvatoryal koordinat sistemindeki koordinatlarını içeren $ra$ ve $dec$ sütunlarından exoplanet.eu veritabanı sağlananları atacak ve birer $ra$,$dec$ sütunu bırakacak düzenlemeyi yapınız.

Çözüm 3.

pandas.merge() işlemi sırasında her iki taraftan aynıı isimle gelecek sütunlardan fonksiyona ilk sağlanan veriçerçevesindekinin sonuna "_x", ikinci sağlanacak veriçerçevesindekinin sonuna ise "_y" eki gelecektir. Bu nedenle sonu "_y" ile biten $ra$ ve $dec$ sütunlarını yine drop() fonksiyonunu uygun şekilde kullanarak atabiliriz.

In [11]:
og.drop(['ra_y','dec_y'], axis=1,inplace=True)

Daha sonra da ra_x ve dec_x isimli sütunları yeniden isimlendirerek amacımıza ulaşabiliriz. Bunun için veriçerçeveleri üzerinde tanımlı rename() fonksiyonunu aşağıdaki şekilde istediğimiz değişiklikleri bir sözlük değişkenine yazıp, bu değişkeni columns parametresine sağlayarak kullanmalı ve yine yaptığımız değişikliği kalıcı hale getirmek için fonksiyonun inplace parametresini $True$ değerine ayarlamalıyız.

In [12]:
og[['ra_x','dec_x']].head()
Out[12]:
ra_x dec_x
pl_name
11 Com b 185.178779 17.793252
11 UMi b 229.274595 71.823943
14 And b 352.824150 39.235837
14 Her b 242.602101 43.816362
16 Cyg B b 295.465642 50.516824
In [13]:
og.rename(columns={'ra_x':'ra','dec_x':'dec'},inplace=True)
og[['ra','dec']].head()
Out[13]:
ra dec
pl_name
11 Com b 185.178779 17.793252
11 UMi b 229.274595 71.823943
14 And b 352.824150 39.235837
14 Her b 242.602101 43.816362
16 Cyg B b 295.465642 50.516824

Gördüğünüz gibi istediğmiz değişiklikleri yaptık ve bağlanmış veritabanımızı her iki veritabanında ortak olan ötegezegenler için her iki veritabanında ortak olmayan bilgilerini de içerecek şekilde her türlü analiz için hazır hale getirmiş olduk. Herhangi bir veri için tekrar orjinal veritabanlarına dönmemiz gerekse de bu veritabanlarını sırasıyla $nasaexo$ ve $exoeu$ veriçerçevelerinde sakladığımız için bir kaybımız olmayacak.

Soru 4.

Sadece geçiş yöntemiyle keşfedilmiş gezegenlerden oluşan bir veriçerçevesi oluşturunuz.

Çözüm 4.

Bu amaçla yapmamız gereken daha önce de yaptığımız gibi bize sadece geçiş yapan gezegenleri verecek bir koşul üretip bu koşulu mevcut veritabanında uygulayarak bir maske oluşturmak ve uyanları yeni bir veritabanına toplamaktan ibaret. Ancak önce keşif yöntemlerinin hangileri olduğunu görelim. Bunun için discoverymethod sütununa bakmalı ve bu sütundaki tüm teknikleri unique() metodunu kullanarak birer kez geçecek listelemeliyiz.

In [14]:
print(og['discoverymethod'].unique())
['Radial Velocity' 'Imaging' 'Transit' 'Transit Timing Variations'
 'Eclipse Timing Variations' 'Microlensing'
 'Orbital Brightness Modulation' 'Pulsar Timing']
In [15]:
print(nasaexo['discoverymethod'].unique())
['Radial Velocity' 'Imaging' 'Eclipse Timing Variations' 'Transit'
 'Transit Timing Variations' 'Astrometry' 'Disk Kinematics' 'Microlensing'
 'Orbital Brightness Modulation' 'Pulsation Timing Variations'
 'Pulsar Timing']
In [16]:
print(exoeu['detection_type'].unique())
['Radial Velocity' 'Imaging' 'Primary Transit' 'Astrometry' 'Other' 'TTV'
 'Microlensing' 'Timing' 'Radial Velocity, Astrometry'
 'Radial Velocity, Primary Transit' 'Primary Transit, Radial Velocity']

Geçiş yöntemiyle keşfedilen gezegenlerin discoverymethod sütununda $Transit$ adıyla listelendiğini görmüş olduk. Koşulu buna uygun olarak yazabiliriz.

In [17]:
kosul = (og['discoverymethod'] == 'Transit')
gecis_og = og[kosul]
gecis_og.shape
Out[17]:
(3579, 157)

Gördüğünüz gibi her iki veritabanında (NASA ve exoplanet.eu) ortak olan 4443 ötegezegenden 3464'ü geçişle keşfedilmiş (4 Nisan 2023 itibarı ile güncel). Bu önemli bir yüzde. Elimizdeki bu veriçerçevesinde NASA Exoplanet Arcihve'da bulunan onaylanmış tüm geçiş yapan ötegezegenler olduğuna göre bu ötegezegenlerin kütle ve yarıçapları biliniyor olmalı.

Soru 5.

Geçiş yapan ötegezegenler için bir kütle-yarıçap grafiği oluşturunuz.

Çözüm 5.

Çok kolay görünen bu iş için öncelikle elimizdeki verinin gerçekte kütle ve yarıçapları bilinen verilerden oluşup oluşmadığını sorgulamalıyız. Bunun için isnull() fonksiyonunu kullanalım.

In [18]:
gecis_og[gecis_og['pl_bmassj'].isnull()]['pl_bmassj']
Out[18]:
pl_name
K2-253 b       NaN
Kepler-302 c   NaN
Kepler-468 b   NaN
Kepler-487 b   NaN
Kepler-490 b   NaN
Kepler-548 b   NaN
Kepler-553 c   NaN
Kepler-670 b   NaN
Kepler-686 b   NaN
Kepler-706 b   NaN
Kepler-723 b   NaN
Kepler-730 b   NaN
Kepler-731 b   NaN
Kepler-762 b   NaN
Kepler-785 b   NaN
Name: pl_bmassj, dtype: float64

Gördüğünüz gibi durum hiç de öyle değil. Bildiğiniz gibi geçiş yöntemi gezegen yarıçapının yıldız yarıçapına oranının bulunmasını sağlar, yıldız modellerinden elde edilen yıldız yarıçapları kullanılarak gezegen yarıçapları elde edilebilirken kütlelerini elde etmek mümkün değildir. Burada dikine hız (ya da bir başka yöntemle) kütleleri onaylanmamış gezegenler (adaylar) de bulunuyor; hatta çoğunluktalar (2125 / 2772). Bunun için yapabileceğimiz pek fazla bir şey yok; zira bu gezegenlerin büyük çoğunluğu, ki bunların da büyük bölümü de Kepler uzay teleskobuyla keşfedilmiş gezegenlerdir; dikine hızlarını elde etmek üzere yüksek çözünürlüklü tayfları alınamayacak kadar sönük yıldızların etrafında bulunuyorlar. O vakit sadece kütlesi bulunanlara odaklanalım. Ancak önce yarıçapların da bulunup bulunmadığını bir test edelim. isnull() fonksiyonu kullanabileceğimiz gibi isna() fonksiyonunu da kullanabiliriz çünkü veriçerçevemizde değer bulunmayan bütün sütunlar NaN olarak işaretmenmiş durumda.

In [19]:
gecis_og[gecis_og['pl_radj'].isna()]['pl_radj']
Out[19]:
Series([], Name: pl_radj, dtype: float64)

İşte bu şaşırtıcı. Zira geçiş yöntemiyle keşfedilmiş 16 ötegezegenin veriçerçevemizde yarıçapları bulunmuyor. Bunun nedeni basit olarak bu değerlerin veritabanına girilmemiş olması olabilir. Astronomide (ya da veri bilimi içeren herhangi başka bir alanda) kullanılan veritabanlarında bu durumla sıklıkla karşılaşılır. Bu tür durumlarda bu bilgiler başka veritabanlarında ya da literatürden alınabilir. Ya da sadece bu durumu yönetmekle yetinilir. Bir başka deyişle, iş eldeki veriyle yapılıp bu durum sonuçların paylaşıldığı yerde belirtilir. 4 Nisan 2023 tarihi itibarı ile ortak tabloda geçiş yöntemiyle keşfedilip yarıçapı veritabanına girilmemiş gezegen bulunmamaktadır. Ancak tekrar oluşabilecek böyle bir durum için aşağıdakine benzer bir çözüm takip edilebilir:

Biz örneğimizde yarıçap değerlerini barındıran pl_radj sütununu NASA Exoplanet Archive'dan almıştık. Bu gezegenler exoplanet.eu veritabanında da bulundukları için orada yarıçapları bulunuyor olabilir. Dolayısıyla yukarıdaki koşulun sağlandığı gezegenlerin yarıçap değerlerini exoplanet.eu ($exoeu$) veritabanından alıp, veriçerçevemizdeki pl_radj sütununa kopyalayabiliriz. Öncelikle exoplanet.eu veritabanında bu gezegenlerden hangilerinin yarıçaplarının olduğuna bakalım. Bunun için $exoeu$ şeklinde adlandırdığımız bu veritabanının indeks sütununu gezegen adının bulunduğu # name sütununa ayarlayalım ve gecis_og veriçerçevemizde yarıçapı bulunmayan (NaN olan) gezegenlerin bu veritabanında olup olmadığını sorgulayalım. Yarıçap değerleri $exoeu$ veriçerçevesinde $radius$ sütununda bulunmaktadır.

In [20]:
exoeu.set_index('name', inplace=True)
for planet in gecis_og[gecis_og['pl_radj'].isna()]['pl_radj'].index:
    print(planet,exoeu.loc[planet,'radius'])

Gördüğünüz gibi bu değerler exoplanet.eu veritabanında bulunuyor. Bulunmuyor da olabilirdi. Bu durumda da gidip başka bir veritabanına bakabilir ya da literatürden toplayıp manuel olarak kendimiz girebilirdik. Ama buna gerek kalmadı. Yukarıdaki gibi bir döngü yapısıyla ilgili satırlara gereken bilgileri ekleyebiliriz.

In [21]:
for planet in gecis_og[gecis_og['pl_radj'].isna()]['pl_radj'].index:
    gecis_og.at[planet,'pl_radj'] = exoeu.at[planet,'radius']
print(gecis_og[gecis_og['pl_radj'].isna()]['pl_radj'])
print(gecis_og.at['WASP-18 b','pl_radj'])
Series([], Name: pl_radj, dtype: float64)
1.24

Görüldüğü üzere artık yarıçap bulunmayan sütun yok. Geçiş yöntemiyle keşfedilen tüm gezegenler için bu değerin belirlenmiş olması gerektiğinden bu bilgiyi veriçerçevemizde bulundurmak istedik. Ancak bu gezegenlerin tümü için kütle değerinin veriçerçevemizde olmadığını gördük. Ancak amacımız olan kütle-yarıçap grafiğini seaborn paketi fonksiyonları kullanarak çizdirirken bu durum bir problem teşkil etmeyecek. Çünkü kütlesi veriçerçevesinde bulunmayan gezegenler dikkate alınmayacak. Söz konusu parametreleri numpy dizilerine alarak matplotlib.pyplot fonksiyonları ile grafik elde etmek isterseniz bu durumu dikkat almanız gerekecektir.

In [22]:
from matplotlib import pyplot as plt
%matplotlib inline
plt.plot(gecis_og["pl_bmassj"], gecis_og["pl_radj"],'b+')
plt.xlabel("Kutle (M$_{jup}$)")
plt.ylabel("Yaricap (R$_{jup}$)")
plt.show()

Görüldüğü üzere bu veritabanlarından birinde (NASA Exoplanet Archive) bazı düşük kütleli yıldızlar da bulunmaktadır. Bunları seçerek veritabanından çıkarmakta fayda var.

In [23]:
gecis_og = gecis_og[gecis_og['pl_bmassj'] < 100]
In [24]:
plt.plot(gecis_og["pl_bmassj"], gecis_og["pl_radj"],'b+')
plt.xlabel("Kutle (M$_{jup}$)")
plt.ylabel("Yaricap (R$_{jup}$)")
plt.show()

Bu grafik genellikle farklı gezegen türleri için çizdirildiğinde anlam kazanan bir grafiktir. Bu nedenle yine daha önce yaptığımız gibi kütle limitleri koyarak kütle-yarıçap grafiğini farklı gezegen grupları için elde edebiliriz. Örneğin $0.1 - 0.4~M_{jup}$ kütle aralığındaki gezegenler için böyle bir uygulama yapalım.

In [25]:
kosul = (gecis_og['pl_bmassj'] >= 0.1) & (gecis_og['pl_bmassj'] <= 0.4)
saturnler = gecis_og[kosul]
plt.plot(saturnler["pl_bmassj"], saturnler["pl_radj"],'b+')
plt.xlabel("Kutle (M$_{jup}$)")
plt.ylabel("Yaricap (R$_{jup}$)")
plt.title("Gecis Yapan Saturn Kutlesindeki Gezegenler Icin Kutle-Yaricap Grafigi")
plt.show()

Bu grafikte bir doğru üzerine dizilen gezegenler için kütle değeri kütle-yarıçap ilişkilerinden türetilmiş olmalıdır. Bu gezegenler için barınak yıldızlarının sönük olması nedeniyle dikine hız alınmamış olabilir, ayrıca gezegen kütlesini belirlemeye yardımcı olabilecek, gözlenebilecek düzeyde bir geçiş zamanlaması değişimi yaratabilecek bir ilave cisim bulunmayabilir. Grafikte daha ilgi çekici olan, genel olarak Satürn kütlesi civarındaki gezegenler için saçılması yüksek de olsa kütleyle yarıçap arasında bir pozitif korelasyonun gözlendiği, ancak yarıçapı $0.25 R_{jup}$''ten küçük gezegenler için bu ilişkinin bozulduğudur. Bu ilginç bir araştırma sorusu olabilir; ancak öncelikle bu verilerin kaynağına bakmak ve grafiği bir de belirsizlik değerleriyle birlikte çizdirmeyi denemekte fayda vardır.

In [26]:
kosul = (gecis_og['pl_bmassj'] < 0.04)
karasal = gecis_og[kosul]
plt.plot(karasal["pl_bmassj"], karasal["pl_radj"],'b+')
plt.xscale("log")
plt.yscale("log")
plt.xlabel("Kutle (M$_{jup}$)")
plt.ylabel("Yaricap (R$_{jup}$)")
plt.title("Gecis Yapan Karasal Gezegenler Icin Kutle-Yaricap Grafigi")
plt.show()
In [27]:
kosul = (gecis_og['pl_bmassj'] > 0.5)
devgaz = gecis_og[kosul]
plt.plot(devgaz["pl_bmassj"], devgaz["pl_radj"],'b+')
plt.xlabel("Kutle (M$_{jup}$)")
plt.ylabel("Yaricap (R$_{jup}$)")
plt.title("Gecis Yapan Dev Gaz Gezegenler Icin Kutle-Yaricap Grafigi")
plt.show()