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
Jupyter temel olarak metin, görsel, kod (Python, R ve Julia başta olmak üzere çeşitli program dillerinde yazılmış), kod çıktısı ve işaretle dillerinin (html, latex) bir arada kullanılabildiği bir platformdur. Bu ders Jupyter platformu üzerinden işleneek olup, öğrencinin temel fonksiyonları biliyor olmasının yanı sıra bazı kısa yolları ve ileri düzey yapıları kullanabiliyor olması kendi yararına olacaktır. Jupyter hakkında daha geniş bilgiye Jupyter sitesinden ulaşabilirsiniz. Jupyter ve Python'u kurmak için bu derste önerilen yöntem olan Anaconda üzerinden kurmak için AST415 Astronomide Sayısal Çözümleme-I Ders 1. Unix ve Python'a Giriş 'in sonuna doğru görsellerle verilen anlatımdan yararlanabilirsiniz.
Jupyter'la etkileşebileceğiniz iki temel yöntemden birincisi kod çalıştırmaktır. Bu nedenle Jupyter defterlerinin temel birimi olan hücrelerin (cell) varsayılan türü kod çalıştırmaya (Code cell) yöneliktir. Yapmanız gereken tek şey yeni (Insert --> Cell Below) ya da b kısayol tuşuna basarak bir hücre oluşturup, o hücrenin içerisinde kodunuzu yazmanızdır. Yeni oluşturulan bir Jupyter defteri zaten boş bir kod hücresiyle açılır. Bir kod hücresi içine istediğiniz uzunlukta kod yazabilirsiniz. Jupyter hücresinin başında yazdığınızı bir girdi (input) olduğunu gösteren In ifadesi ve yanında köşeli parantez içinde çalıştırıldığı vakit, çalıştırılan kaçıncı kod olduğnu gösteren bir tam sayı yer alır. Kodunuzu kod hücresi içinde yazdıktan sonra çalıştırmak için Run aracını () ve Cell --> Run Cells menü seçeneklerini kullanabileceğiniz gibi Ctrl+Enter seçeneği ile kodunuzu çalıştırıp o hücre içinde kalabilir, Alt+Enter tuş takımı ile kodunuzu çalıştırıp alta yeni bir hücre (kod hücresi açabilir ya da Shift+Enter seçeneği ile kodunuzu çalıştırıp varsa bir sonraki hücreyi seçebilirsiniz. Kodunuzu her çalıştırmanız sonrasında o kodun çalıştırılma sayısı (In [ ] ) bir artacaktır.
Dikey atış problemini çözen bir Python kodu aşağıda örnek olarak verilmiştir.
v0 = 5 # Ilk hiz m/s
t = 0.6 # zaman s
g = 9.81 # yercekimi ivmesi m/s**2
y = v0*t - 0.5*g*t**2
print(y)
Kod, kod hücresine yazılırken; çalıştırıldığında çekirdete (Kernel) çalıştırılır. Çekirdeğe ilişkin işlemler Kernel menüsünden ya da araç çubuğundaki , gibi butonlarla çalıştırılabilir, dudurulabilir ya da yeniden tüm çekirdek yeniden başlatılabilir.
Jupyter'da herhangi bir metin yazmak için hücreyi tıklayarak ya da hücrenin içine girilmişse ESC tuşuyla hücre seçilmelidir. Aktif bir hücre yeşil renkte bir çerçeveyle, seçili bir hücre ise mavi renkte bir çerçeveyle çevrilidir. Hücre seçildikten sonra türü istenirse Araç Çubuğu'ndaki drop-down menüden Markdown seçeneği seçilerek, istenirse de kısaca m tuşuna basılarak metin moduna dönüştürülür. Aynı şekilde bir hücreyi kod hücresine dönüştürmek istediğinizde araç çubuğundaki menüyü kullanabileceğiniz gibi y kısayol tuşundan da faydalanabilirsiniz. Bu durumda kod satırlarındaki In [ ] ifadesi hücre başında yer almaz. Şu ana kadar bu Jupyter defterinin tüm metin hücreleri bu şekilde oluşturulmuştur. Örnek olarak inceleyebilirsiniz.
Metin hücrelerinde latex ve html işaretleme dillerini kullanablirsiniz. Dikey atış kodu örneğindeki formül
$$ y = V_0 t - \frac{1}{2} g t^2 $$
ifadesi ile verilebilir. $ işareti satır içinde latex ifadesi kulllanmak, $$ ise yazılan latex ifadesini yeni bir satırın ortasına almak için kullanılabilir.
Ayrıca metinlerinizde html etiketlerini (tag) kullanarak bold, italik, altı çizili metinler yazabilir, metinlerinize link verebilir ya da renklendirebilirsiniz!
Çizdiğiniz grafikleri Jupyter defterinizde göstermek ve .py uzantılı dış programları çalıştırmak gibi bu derste sıkça ihtiyaç duyacağınız bazı aksiyonlar için Jupyter'da "sihirli sözcükler" (magic words) adı verilen yapılardan yararlanmanız gerekecektir. Bir örnek aşağıda verilmektedir.
% matplotlib inline
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0,9,10)
y = x**2
plt.plot(x,y,'r--')
plt.xlabel('x')
plt.ylabel('$y^2$')
plt.title("x'in karesi")
plt.show()
Jupyter'da kullanılabilecek bazı kullanışlı sihirli sözcükler aşağıda listelenmiştir.
%paste & %cpaste: Başka bir kaynaktan ya da terminalden kod kopyalarken ">>>" prompt sembollerini atarak sizin sadece kodu kopyalamanızı sağlar.
%run: Bu derste sıkça kullanacağınız bir sihirli sözcük olup, py uzantılı kodlarınızı Jupyter içinden çalıştırmanıza olanak sağlar (Örnek: %run deneme.py)
%timeit: Kodunuzu zamanlamanıza olanak sağlar (Örnek: %timeit L = [x ** 2 for x in range(1000)])
%xmode: Hata mesajlarının gösterilme şeklini belirler. Plain, Verbose ve Context olmak üzere üç çeşit hata mesajı alma modu bulunmaktadır.
%debug: Herhangi bir hata mesajı aldığınızda, kodun hata veren noktasına gidip bir hata ayıklama (debug) kutucuğu (prompt) açar ve sizden kodu düzeltmenizi bekler.
%pdb on: Jupyter'ın varsayılan davranışının bir hatayla karşılaşıldığında debug prompt'u açması şeklinde olmasını istiyorsanız bu sihirli sözcükle sağlayabilirsiniz.
%history: : İlgiil Jupyter defterinin tarihçesini listeler.
%lsmagic: Tüm sihirli sözcüklerin bir listesine erişiminizi saplar
%lsmagic
Hücre silmek ve eklemek için Insert ve Cell menü seçeneklerinden uygun olanlarını, araç çubuğundaki simgeleri kullanabileceğiniz gibi, işletim sistemlerinin sağladığı Crtl+c, Crtl+x ve Crtl+v seçenekleri de kullanabilirsiniz. Ayrıca araç çubuğunda bu işlerin yanı sıra satır taşımak için kullanabileceğiniz araçlara erişiminizi sağlayan butonlar da bulunmaktadır. Ancak en pratiği kısa yol tuşlarını kullanmaktır. Bu noktada tavisye kısa yol tuşlarını öğrenmek ve verimlilik açısından klavyeden elinizi ayırmadan (ve böylece yazdığınız şeye konsantrasyonunuzu kaybetmeden) bu tuşları kullanmanız olacaktır. a tuşunu bulunulan hücrenin üstüne, b tuşuna altına hücre eklemek,
Jupyter'da herhangi bir konuda yardım almak ve tanımlı kısayol tuşlarını öğrenmek için Help menüsündeki seçeneklerden yararlanabilirsiniz. Bu bölümde Python'la kod yazarken ve bazı önemli paketleri (modülleri) kullanırken sorunlarla karşılaştığınız zaman nasıl yardım alabileceğinize ilişkin bazı ipuçları verilecektir.
help(len)
Aynı seçeneğe erişmek için daha kısa bir yol ise yardım almak istediğiniz fonksiyonu yazıp sonuna ? koymaktır. İşletim sistemi ve kullanılan tarayıcıya bağlı olarak standard bir çıktı alınabileceği gibi yardım içeriğini taşıyan bir pencere (pop-up window) de açılabilir.
len?
Sadece ön tanımlı fonksiyonlar değil, çeşitlli nesneler üzerine tanımlı metotlara (ing. attribute) ulaşmak için aynı yöntemler kullanılabilir.
L = ['1', 3.14, 2]
help(L.insert)
L?
Herhangi bir fonksiyonun (kulllanıcı tanımlı ya da değil) dokümantasyon bloğu (docstring) varsa, ona ulaşarak da fonksiyonun (sınıfın ya da kod parçasının) nasıl kullanılabileceği konusunda da bilgi alınabilir.
def daire(r = 1):
"""
r yaricapina sahip bir dairenin
cevresini ve alanini hesaplayip
programa dondurur.
Kullanilisi:
alan, cevre = daire(R)
Input:
r : Dairenin yaricapi
Output:
alan = pi*r**2
cevre = 2*pi*r
Ornek:
R = 5
print(daire(R))
Cikti:
78.53981633974483 31.41592653589793
"""
from math import pi
return pi*r**2, 2*pi*r
R = 5
alan, cevre = daire(R)
print("Yaricapi {:g} birim olan bir dairenin alani {:g} birimkare, cevresi {:g} birimdir".\
format(R,alan,cevre))
print("-----------------------------------------")
print("Daire fonksiyonu dokumantasyon blogu:")
print("-----------------------------------------")
help(daire)
Fonksiyonun kaynak koduna ulaşmak için fonksiyon adını takiben ?? kullanılır.
daire??
Eğer bu opsiyon (??) sadece iç dokümantasyon bloğunu veren ? ile aynı çıktıyı veriyorsa bu durumda bu fonksiyon Python dışında bir programcılık diliyle kodlanıp, Python'a entegre edilmiş olabilir.
len??
Ayrıca tam adını hatırlayamadığınız fonksiyonları hatırlamak ya da bütün fonksiyonun adını yazmamak için fonksiyonun hatırlayabildiğiniz ya da yazmak istediğiniz kadarını yazdıktan sonra TAB tuşuna basarak geri kalanını iPython'ın yazmasını isteyebilirsiniz.
# Daha once tanimladiginiz L listesi uzerinde hangi metotlarin
# tanimli oldugunu gormek icin L yazip nokta koyduktan sonra
# <TAB> tusuna basiniz
Ayrıca nesnenin üzerinde tanımlı gizli metotları da görmek isterseniz; nesne_adi._ yazdıktan sonra TAB tuşuna basabilirsiniz.
# Daha once tanimladiginiz L listesi uzerinde hangi gizli metotlarin
# tanimli oldugunu gormek icin L._ yazdiktan sonra
# <TAB> tusuna basiniz
TAB ile birlikte wildcard (*, ?) kullanmak, adını ve ilk birkaç harfini hatırlayamadığınız ancak bir kısmını hatırlayabildiğiniz fonksiyon, metot ya da modülleri bulmanıza yardımcı olacaktır.
*Warning?
Tıpkı Python fonksiyonları gibi, IPython sihirli sözcükleriyle tanımlanan fonksiyonlarının da aynı şekilde ulaşılabilen iç dokümantasyon blokları bulunmaktadır.
%timeit?
Herhangi bir sihirli sözcükle ilgili dokümantasyona sözcüğü yazıp Enter'a basarak erişebilirsiniz.
%run
Çekirdek (Kernel) Jupyter'ın interaktif olarak kod çalıştıran bileşenidir. IPython kulllanırken, bu bir Python kodudur. Python'dan başka dillerde çekirdekler olabileceği gibi birden fazla Python versiyonu (2.7, 3.6, 3.8 gibi) sistemde kurulu iseler bulunabilir. Çekirdek Jupyter defterindeki kod parçalarını alır, çalıştırır ve deftere çıktı (output) ya da hata mesajı (error message) yollar.
Çıktı koda bağlı olarak print ifadesi kullanılmamışsa tıpkı input hücreleri gibi Out[ ] ifadesi ile köşeli parantez içinde numarandırılır. print ifadesinin kulllanıldığı durumda çıktı stdout nesnesine yönlendirilr. Kod hatta veriyorsa bu da stderr nesnesi üzerinden gelir.
print("merhaba, stdout")
3 + 5
np.array([1,2,3])
Jupyter'da çıktılar senkronize değildir. Kod bir taraftan çıktı üretir ve ekrana getirirken, siz diğer tarafta başka bir hücre üzerinde çalışıyor olabilirsiniz. Bir hücre çıktı ürettikçe üretilen çıktı bir önceki çıktıdan sonra ekrana gelir. Tüm kod bloğunun çalışıp, tüm çıktıların ekrana tek bir anda basılması beklenmez.
import time, sys
for i in range(5):
print(i)
time.sleep(0.8)
Kod bloklarının uzun çıktılar vermesi durumunda çıktının olduğu blok isteğe göre büyütülüp küçültülebilir. Aşağıdaki kod parçasının çalıştırıldıktan sonra verdiği çıktıyı küçültmek için çıktı hücresinin sol tarafında beliren alana tek (sağ tarafta bir kaydırma çubuğu için) ya da çift (çıktı bloğunu tamamen kapatmak için) tıklayınız.
for i in range(60):
print(i)
Eğer kodun çıktsı çok uzunsa tarayıcı bunun için bir kaydırma çubuğunu otomatik olarak sağlar.
from math import pi
for r in range(500):
print(2*pi*r)
Jupyter defterlerinde In tüm girdilerin (inputs), Out ise çıktıların tutulduğu birer Python listesidir. İstenen girdi ya da çıktı istendiği vakit ekrana getirilebilir ya da üzerinde işlem yapılabilir.
print(In[1])
x = 2.0
y = 2*x**2 - 2*x + 4
y
print(Out[23]) # Sizde 25. output olmayabilir, dogru sayiyla calistiriniz
Out[23]*3*x**2
print() son çıktıyı, print() bir öncekini, and print() ondan öncekini ... verir
print(_)
print(__)
Out[25] için bir kısa yol _25 yazmaktır.
import math
_25-math.sin(math.pi/2)
Sonuna ";" işareti koyduğunuz kod bloğu çalışır ama ekrana çıktı vermez. Bu yapıyı sıklıkla kullanmanız gerekebileceğinden öğrenmenizde fayda vardır.
math.sin(2) + math.cos(2);
Bu durumda bu satırın vereceği çıktıya da Out[x] ile (ya da _x ile) erişmek mümkün değildir.
Out[27] # Bir önceki kod satiri hangi sayiya sahipse onu kullaniniz
%history ilgili Jupyter defterinde çalıştırılmış kod bloklarının numaralarını almak için kullanılabilir.
%history -n 20-23
Bu derste ihtiyaç duyulacak temel Python programlama bilgisi Ankara Üniversitesi Fen Fakültesi Astronomi ve Uzay Bilimleri Bölümü 4. sınıf seçmeli dersi AST415 Astronomide Sayısal Çözümleme-I dersinde verilmektedir. Bu derse başlamadan önce AST415'in internet sayfasına eriştikten sonra ders notlarını indirmeniz, anlayarak okumanız, kod yazarak çalışmanız, alıştırmalarını ve ödev sorularını yapıp cevaplarıyla karşılaştırmanız önerilir. Bu nedenle 800100715151 Astronomide Veritabanları dersini alacak tüm yüksek lisans / doktora öğrencilerine bu çalışmayı ders başlamadan yapmalarını öneriyoruz. İdealinde bu dersi AST415 almış ya da bir başka şekilde Python diliyle programlamaya aşina öğrencilerin almasıdır. Ancak yüksek lisans derslerine önkoşul koyamadığımız için programlama bilgisi yeterli olmayan öğrencilerimize AST415 notlarına iyi çalışmalarını önermekle yetiniyoruz. Aşağıda seçilmiş 8 soru 1. ödev olarak verilmiştir. Bu ödevi anlayarak yapabiliyor olmanız durumunda bu dersin gerektirdiği Python programlama bilgisinin asgari düzeyine sahip olduğunuz varsayılabilir.
Bu derste sıkça kullanacağımız numpy ve scipy paketleri için ise özel bir girişe ihtiyaç duyduk. Bu paketleri özet olarak anlatırken Python'la ilgili bazı temel yapıları da tekrar görmenizi, hatırlamanızı ve daha iyi öğrenmenizi de amaçladık.
Numpy, Python için temel bilimsel fonksiyonların bulunduğu bir pakettir. Sağladığı N-boyutlu dizi nesnesi yardımıyla matematiksel işlemler ve fonksiyonların uygulanmasını kolaylaştırır ve lineer cebirden Fourier dönüşümlerine kadar pek çok konuda gelişmiş fonksiyonlar sunar.
Bu işlemleri optimize gerçekleştirebilmesi için numpy'ın temel nesnesi olan dizi nesnesi, listelerden farklı olarak aynı tür (float) veri içerir ve sabit uzunlukta tanımlanır. Aritmetik işlemlerin ve vektörel (diziler üzerinde işlem yapmak üzere) tanımlanmış fonksiyonların döngü tanımlanmaksızın tek bir kerede uygulanmasını sağlaması itibarı ile ayrıca pratiktir.
Bir numpy dizisi oluşturmak için sıklıkla kullanılan iki fonksiyon bulunmaktadır; npp.arange ve np.linspace. Öncelikle bu iki fonksiyona bakalım.
# Oncelikle numpy modulunu cagiralim (import edelim)
# numpy modulunun standart lakabi np 'dir.
import numpy as np
a = np.arange(0,15,1) # O'dan 15'e (15 haric) 1er aralikli sayilardan olusan dizi
print("a: ", a)
# baslangic noktasinin varsayilan degeri 0, adim buyuklugununki 1 oldugundan
# ayni dizi asagidaki sekilde de tanimlanabilir.
a = np.arange(15)
print("a: ", a)
# Linspace'de ise baslangic, son (son dahil) ve adim buyuklugu yerine
# dizide kac eleman istendigi bilgisi saglanir
b = np.linspace(0,9,10)
print("b: ", b)
Bir listeyi ya da diziye dönüştürülebilecek herhangi başka bir seriyi (ing. iterable) bir numpy disizine dönüştürmek üzere ise np.array fonksiyonu kullanılır.
liste = [1, 2, 3, 4, 5]
c = np.array(liste)
print("c: ", c)
seri = range(12)
d = np.array(seri)
print("d: ", d)
Ayrıca ihtiyaca göre (örneğin toplayarak ilerlemek üzere) sıfırlardan (ya da çarparak ilerlemek üzere) birlerden oluşan diziler oluşturmak üzere de sırasıyla np.zeros ve np.ones fonksiyonları kullanılır.
sifirlar = np.zeros(5)
print("5 tane 0'dan olusan dizi:", sifirlar)
birler = np.ones(8)
print("8 tane 1'den olusan dizi: ", birler)
np.linspace'e çok benzeyen ancak eşit aralıkları logaritmik olarak düzenleyen bir de np.logspace fonksiyonu bulunmaktadır.
loga = np.logspace(1,5,5)
print("loga : ", loga)
Bir fonksiyona dayalı olarak bir numpy dizisi oluşturmak için np.fromfunction fonksiyonunu kullanabilirsiniz.
dizi = np.fromfunction(lambda i, j: i * j, (4, 4), dtype=int)
print(dizi)
numpy'da nümerik dizilerde indeksleme ve dilimleme çok önemli bir fark dışında listelerdekiyle aynı şekilde yapılır. Bu çok önemli fark dilimlerin orjinal dizinin bir kopyası olmayıp gerçekten bir bölümü olmasıdır. Dolayısı ile dilim üzerinde bir değişiklik yapıldığı vakit orjinal dizide de bu dilimin karşılık geldiği elemanlar değişir!. Bazı
a = np.linspace(10,50,9)
print("a: ", a)
# linspace reel sayilardan (float) mutesekkil bir dizi yaratir
print("a[0]: {:.2f}, a[-1]: {:.2f}, a[5]: {:.2f}".format(a[0],a[-1],a[5]))
print("a[:5]: ", a[:5])
print("a[7:]: ", a[7:])
print("a[3:7]: ", a[3:7])
print("a[0:-1:2]: ", a[0:-1:2])
print("a[::4]: ", a[::4])
print("a[1:-1]: ", a[1:-1])
b = a[1:-1]
print("b: ", b)
b[2] = 0.1
print("Yeni b: ", b)
print("a: ", a)
Nümerik dizilerde indeksleme ve dilimleme işlemlerinde getirdiği pratik kullanım faydaları açısından $a[range(f:t:i)]$ yapsını incelemek gerekir. Bu yapı $a[f:t:i]$ yapısyla aynıdır ve $a$ dizisinin $f$ indeksinden başlayıp $t$ indeksine kadar ($t$ hariç), $i$ büyüklüğündeki adımlarla elemanlarının alınması ve istenirse değiştirilmesine yarar.
import numpy as np
a = np.linspace(72,79,8)
print("a = ", a)
a[[1,6,7]] = 100 # 1., 6. ve 7. indekslerin değerini 100 yap
print("a[[1,6,7]] = 10 -->", a)
# range 2 ile 8 indeksler arasinda (8 haric) 3er atlayarak indeks degerlerini uretir
a[range(2,8,3)] = -2
print("a[range(2,8,3)] = -2 -->", a)
Daha da pratik ve oldukça kullanışlı bir indeksleme ve dilimleme yöntemi de boolean ifadelere dayanandır. Aşağıda verilen örneklerde göreceğiniz gibi boolean ifadeler de indeksleme ve dilimleme için kullanılabilir.
import numpy as np
a = np.linspace(-4,5,10)
print("a[a < 0] -->", a[a < 0])
# negatif elemanlari a dizisinin maksimumu degeri yap
a[a < 0] = a.max()
print("a[a < 0] = a.max() -->", a)
# 1., 6. ve 7. indekslerin değerini 10 yap
a[[1,6,7]] = 10
print("a[[1,6,7]] = 10 -->", a)
# a'daki 10lari verilen baska bir diziden sirayla secilen elemanlarla degistir
a[a == 10] = [10, 20, 30]
print("a[a == 10] = [10, 20, 30] -->", a)
# a > 2 returns True for elements of a larger than 2 and False otherwise
print(a > 2)
numpy'da çok boyutlu diziler satırları öne alan (row major storage) yapıda saklanır. Aşağıdaki örnekte oluşturan a dizisinin her bir satırının $[ ]$ arasında tutulduğuna, sütunların ise ayrılmadığına dikkat ediniz.
a = np.arange(15).reshape(3,5)
print("a: \n", a)
Dizi içinde belli bir elemanın yerini belirlemek (indekslemek) için aşağıdaki yazım kurallarından herhangi biri kullanılabilir.
print("a[1,2]: ", a[1,2])
print("a[1][2]: ", a[1][2])
Benzer bir mantığı takip ederek dilimleme de yapabilirsiniz.
# a dizinin 0 ile 2. satir arasi (2 haric)
# 1 ve 4 sütunlar arasi (4 haric)
print("a[0:2,1:4]: \n",a[0:2,1:4])
# a dizisinin bastan sona birer atlayarak tum satirlari
# ve son satir haric tum sutunlari
print("a[::2,:-1] \n", a[::2,:-1])
Herhangi bir sütuna ulaşmaya çalışırken numpy'ın satırı öncelediği akılda tutulmalıdır.
print("a[:,2]: ", a[:,2])
Satırları tek tek yazdırmak için bir for döngüsü kullanmak isteyebilirsiniz ancak önerilen Python dizilerini eleman eleman ya da satır satır taramak için döngüleri kullanmanız yerine dilimleri kullanmanızdır, çünkü bu yol çok daha hızlıdır.
# Satir uzerinden ilerleme
i = 1
for satir in a:
print("{:d}.satir: {:s}".format(i, str(satir)))
i += 1
# Sutun uzerinden ilerleme
for j in range(a.shape[1]):
print("{:d}.sutun: {:s}".format(j, str(a[:,j])))
j += 1
Bir numpy dizisi üzerine tanılanmış pek çok metot bulunmakla birlikte sıklıkla kullanılanları aşağıda örneklenmiştir.
a = np.arange(15)
print("a dizisinin boyutu: ", a.ndim)
print("a dizisinin sekli: ",a.shape)
print("a dizisinin eleman sayisi: ",a.size)
print("a dizisinin elemanlarinin turu: ",a.dtype)
print("a dizisinin eleman buyuklugu:b ",a.itemsize)
print("a dizisinin turu: ", type(a))
Ayrıca diziler ve üzerinde yapabileceğiniz işlemler ve tanımlı metotlar hakkında daha fazla bilgi almak için help fonksiyonundan faydalanabilirsiniz.
help(a)
Dizilerin eleman sayısına uygun şekilde şeklini (satır x sütun 'dan oluşan bir matris şeklinde düşünebilirsiniz) değiştirebilmek için np.reshape fonksiyonundan aşağıdaki örnekte olduğu gibi yararlanabilirsiniz.
a = np.arange(15)
print("Degisiklik oncesi a dizisi: \n", a)
print("Degisiklik oncesi a dizisinin boyutu: ", a.ndim)
print("a dizisinin eleman sayisi: ", a.size)
a = a.reshape(3,5)
print("Degisiklik sonrasi a dizisi: \n", a)
print("Degisiklik sonrasi a dizisinin boyutu: ", a.ndim)
print("a dizisinin eleman sayisi: ", a.size)
nxn bir birim matris formunda bir numpy dizisi oluşturmak için np.eye fonksiyonunu kullanabilirsiniz. Uyarı: numpy 'da matrix nesnesi dizi (array) nesnesinden farklıdıır.
i4 = np.eye(4)
print("4x4 birim matris formunda dizi: \n", i4)
numpy dizileri ile çalışırken atama operatörü ("=") bir kopyalama işlemi yapmak yerine aynı diziye yeni bir isim verilmesini sağlar. Bu nedenle dizilerden herhangi birinde bir değişiklik yapıldığında diğeri de değişir.
a = np.arange(0,4.25,0.25)
print("a: ", a)
b = a
print("b: ", b)
a[2] = 100.0
print("Degisiklik sonrasi a: ", a)
print("Degisiklik sonrasi b: ", b)
Sonuç olarak :
b = a
ifadesiyle herhangi bir kopyalama işlemi yapılmaz. a
ve b
hafızanın aynı adresinde bulunan bir dizi için iki farklı isimldir.
b = a[:]
ifadesi a'nın bir görüntüsünü (view) b'ye alır (_shallow copy_). a ve b aynı hafıza adresindeki dizinin iki farklı adıyken, şekilleri bağımsız olarak tutulur.
b = a.copy()
ifadesiyle a'nın içeriği b'ye kopyalanır ( _deep_ copy). Hafızanın başka bir adresinde a'yla aynı içeriğe sahip ancak ondan farklı isimde bir b dizisi yaratılır. Dolayısyla a'da yapılacak bir değişiklik b'yi; b'de yapılacak bir değişiklik ise a'yı etkilemez.
dizi1 = np.arange(18)
dizi2 = dizi1[:]
dizi1.shape = (3,6)
print("1. dizi: \n", dizi1)
print("2. dizi: \n", dizi2)
dizi2[1] = -1
print("2. dizideki degisiklik sonrasi 1. dizi: \n", dizi1)
print("2. dizideki degisiklik sonrasi 2. dizi: \n", dizi2)
a = np.arange(0,2.1,0.5)
b = a.copy()
print("a: ", a)
print("b: ", b)
b[1:3] = np.array([-100,-1000])
print("a: ", a)
print("b: ", b)
İki diziyi karşılaştırmak ve aynı olup olmadıklarını ve ne düzeyde benzer olduklarını anlamak için çeşitli fonksiyonlar ya da yapılar kullanılabilir.
a = np.arange(1,4.1,0.6)
c = a[:]
print("a: ", a)
print("c: ", c)
print("c = a?:", c is a)
c = c.reshape(2,3)
print("c: ", c)
print(c.base is a)
print(c.flags.owndata)
print(a.flags.owndata)
Python'da, toplama, bir sabitle çarpma gibi bazı işlemler numpy dizileri üzerinde doğrudan uygulanabilir.
a = np.arange(20).reshape(5,4)
print("a: \n", a)
print("3a: \n", a*3)
print("a + a: \n", a + a)
Ancak çarpma ve bölmenin sadece karşılıklı elemanların çarpılması ya da bölünmesinden ibaret olduğu (matris çarpması olmadığı) bilinmelidir. Dolayısı ile çarpma ve bölme sadece aynı şekildeki diziler arasında uygulanabilen işlemlerdir.
print("a^2: \n", a**2)
Ancak matris çarpması da numpy üzerinde yapılabilir ve bunun için @ operatörü kullanılır.
b = np.linspace(10,29,20)
print("a: \n", a)
b = b.reshape(4,5)
print("b: \n", b)
print("a . b: \n", a @ b)
Pek çok fonksiyon diziler üzerinde de kullanılabildiği gibi bazı fonksiyonların diziler için özel olarak tanımlanmış halleri de numpy paketinde bulunabilir.
print("a dizisi elemanlarinin toplami: ", sum(a))
theta = np.arange(0, 2*np.pi+np.pi/32, np.pi/16)
print("cos(a): \n", np.cos(a))
from matplotlib import pyplot as plt
%matplotlib inline
plt.plot(theta, np.cos(theta), "r-")
plt.xlabel("theta")
plt.ylabel("cos(theta)")
plt.hlines(y = 0, xmin=min(theta), xmax=max(theta), lw=1)
plt.show()
np.random.random_sample()
fonksiyonu [0.0, 1.0)
aralığıda rastgele değerlerden oluşan diziler yaratmak için kullanılır. Bu fonksiyonu ve sabitle çarpmayı kullanarak 10x10 bir numpy dizisi oluşturunuz. Dizinin ortalamasını ve standart sapmasını uygun numpy
fonksiyonlarını kullanarak yazdırınız.
Aşağdaki diziyi manuel olarak (elinizle) yazmadan pratik bir yöntemle oluşturunuz. Bu dizinin sadece 1, 3 ve 5. satırları ile 2. sütunundan oluşan bir dizi (vektör) oluşturup, ekrana yazdırınız.
[[1, 6, 11],
[2, 7, 12],
[3, 8, 13],
[4, 9, 14],
[5, 10, 15]]
Kenarlarındaki tüm rakamları 1, ortasındaki tüm rakamları 0 olan nxn bir dizi oluşturmak üzere bir fonksiyon yazınız. Fonksiyonunuz kare dizinin bir kenarını (n) argüman olarak alsın ve bu kurala uygun olarak oluşturduğu nxn diziyi programa döndürsün. Aşağıda 4x4 bir dizi örnek olarak verilmiştir.
1 1 1 1
1 0 0 1
1 0 0 1
1 1 1 1
0 ile 90 derece (0 dahil 90 hariç) arasında beşer derecelik eşit uzaklıklarla birbirinden ayrılan zenit açılarından oluşan, zenit
isminde bir numpy dizisi oluşturunuz. z
zenit açısını, X
hava kütlesini göstermek üzere bu dizinin 60 dereceden küçük tüm elemanlarına $ X = sec(z) $; 60 derece ve ondan büyük bütün elemanlarına; $ X = sec(z) - 0.0018167 (sec(z) - 1) - 0.002875 (sec(z) - 1)^2 - 0.0008083 (sec(z) - 1)^3 $ (Hardie, 1962) formülünü uygulayarak hava kütlesini hesaplayınız ve X
isimli bir dizide toplayarak, bu diziyi ekrana yazdırınız.
yildizlar.dat salt metin dosyasını np.loadtxt()
fonksiyonu ile okuyarak sütunlarını uygun olarak isimlendirdiğiniz dizilerde toplayınız. Yörünge döneminin histogramını bulunduğu diziyi np.histogram()
fonksiyonunu kullanarak oluşturunuz. Fonksiyon çıktı olarak her bir gruptaki (bin) gezegen sayısını ve grubun limitlerini döndürür. Her bir grubun ortalamasını hesaplayarak ekrana yazdırınız.
Standart sapma aşağıdaki ifade ile hesaplanır.
$$ \sigma = \left [ \frac{1}{N} \sum_{i=1}^N (a_i - \bar{a})^2 \right ]^{1/2} $$
Verilen bir a dizisi için
a
dizisinin ortalmasını ($\bar{a}$),a
dizisinin eleman sayısını bölümünü,hesaplayan standart_sapma
isimli bir fonksiyon yazınız. Fonksiyonunuz sadece a
dizisini alsın ve dizinin standart sapmasını döndürsün.
Soru 1. Betelgeuse'un ışınım gücü, Güneş'inkinin 140 000 katı, sıcaklığı ise yaklaşık olarak 3500 K'dir. Güneş'in yüzey sıcaklığını 5780 K, yarıçapını 700 000 km almak üzere gerekli değişken tanımlarını yapıp, iyi bilinen ışınım gücü formülünü de kullanarak Betelgeuse'un yarıçapını Astronomi Birimi cinsinden hesaplayan ve ekrana güzel bir formatla yazdıran bir Python kod parçası yazınız. (1 AB = 149.6 milyon km)
Soru 2. Bir karadeliğin olay ufkunun merkezine uzaklığını tanımlayan Schwarzschild Yarıçapı'nın ifadesi aşağıdaki gibidir.
$$R_{Sch} = \frac{2 G M}{c^2}$$
Geçen sene Dünya üzerindeki büyük radyo teleskop ve dizgelerinin katılımıyla (Olay Ufku Teleskobu, ing. Event Horizon Telescope, EHT) "fotoğrafı çekilen" ilk karadelik olan M87 gökadasının merkezindeki süper kütleli karadeliğin kütlesi $M = 6.4 x 10^9 M_{Güneş}$ 'tir. Bu süper kütleli karadeliğin Schwarzschild yarıçapını Astronomi Birimi'nden hesaplayan bir Python kodu yazınız. ($G = 6.67 x 10^{-11} m^3 kg^{-1} s^{-2}, c = 299792458 m s^{-1}$)
Soru 3. Herhangi bir dalgaboyu bölgesinde görünen parlaklığı verilen iki yıldızdan alınan akılar oranını hesaplayan ve programda çağrıldığı noktaya döndüren pogson isimli bir fonksiyon yazınız. Fonksiyonunuzu görünen parlaklıkları $m_1 = -1^m$, $m_2 = 4^m$ iki yıldızın akıları oranını ($F_1 / F_2$) hesaplayarak test ediniz.
Soru 4. Bir yıldızın görünen parlaklığını kadir biriminde ve Gaia paralaksını miliyaysaniyesi biriminde alarak, yıldızın uzaklığını parsek biriminde ve mutlak parlaklığını kadir biriminde döndüren bir fonksiyon yazınız.
Soru 5. Yazdığınız fonksiyonu test etmek üzere görünen parlaklğı ve Gaia paralaksı istenen birimlerde (sırasıyla kadir ve miliyaysaniyesi) kullanıcı tarafından klavyeden girilen bir cismin uzaklığını ve mutlak parlaklığını 4. soruda yazdığınız fonksiyonu kullanarak ekrana getiren bir Python programı yazınız. Örnek cisimler olarak HD 114762, 51 Pegasi, Kepler-47, HAT-P-19 ve WASP-69'u kullanarak bu cisimler için uzaklık ve mutlak parlaklık hesabı yapınız. Örnek cisimlerin Gaia fotometrik parlaklık (phot_g_mean_mag) ve paralaks değerlerini Gaia veritabanından alabilirsiniz.
Soru 6. Aşağıda Güneş Sistemi gezegenlerinin isimlerinin anahtar,yörünge dönemlerinin Dünya günü, Güneş'e olan uzaklıklarının milyon kilometre cinsinden tanımlandığı birer demette değer olarak tutulduğu bir sözlük degişkeni verilmiştir.
gezegenler = {'Merkur':(88.0, 57.9),'Venus':(224.7, 108.2),'Dunya':(365.25, 149.6),'Mars':(687.0, 227.9), 'Jupiter':(4331.0, 778.6),'Saturn':(10747.0, 1433.5), 'Uranus':(30589.0, 2872.5),'Neptun':(59800.0, 4495.1)}
Bu sözlük değişkenindenki verileri ve matplotlib.pyplot fonksiyonlarını kullanarak Dünya yılı cinsinden yörünge döneminin karesine karşılık Astronomi Birimi cinsinden yörünge yarı-büyük eksen uzunluğunun küpünü, veri noktalarını kırmızı içi dolu daireler ile göstermek ve eksenlere uygun isimler vermek suretiyle çizdiriniz.
Soru 7. Bir önceki soruda çizdirdiğiniz grafikteki ilişkiye, yörünge dönemi ve yörünge yarı-büyük eksen uzunluklarını birer numpy dizisine (array) aldıktan sonra numpy.polyfit fonksiyonlarını kullanarak bir doğru uyumlayınız. Uyumladığınız doğrunun denklemini ekrana yazdırınız. Uyumladığınız bu doğru denkleminde 0 ile 165 yıl arasında 0.1 yıl eşit uzaklığa sahip noktalardan oluşturacağınız bir numpy dizisinin karesini (P2) koyarak yörünge yarı-büyük eksen uzunluklarını küpünü elde ediniz (a3) ve birer numpy dizisinde saklayınız. Bu iki numpy dizisini (P2, a3) 6. sorudaki grafiğinizin üzerine mavi kesiksiz eğri ile çizdiriniz ve grafiğinizi ekrana getiriniz.
Soru 8.
a) Sırasıyla $parlaklik$ ve $uzaklik$ numpy dizilerinde bir grup yıldız için kadir cinsinden verilen görünen görsel parlaklık ve parsek cinsinden uzaklıklarını kullanarak çağrıldığı programa cisimlerin mutlak görsel parlaklığını döndüren uzaklik_modulu isimli bir fonksiyon yazınız.
b) yildizlar.dat salt metin dosyasının birinci sütununda bazı yıldızların adları, ikinci sütununda kadir cinsinden görunen görsel parlaklıkları, üçüncü sütunda parsek cinsinden uzaklıkları, dördüncü sütunda ise Kelvin cinsinden yüzey sıcaklıkları bulunmaktadır. Bu dosyayı açıp satır satır okuyarak her bir satırda yer alan yıldız isimlerini $yildizlar$, görünen görsel parlakliklarını $mV$, uzakliklarını $d$, yüzey sıcaklıklarını $T$ isimli listelere toplayiniz. Not: Sayısal değerleri kayan noktalı sayıya dönüştürmeyi unutmayınız! Dosyayı kapattıktan sonra ilgili numpy fonksiyonunu kullanarak $mV$, $d$ ve $T$ listelerini aynı isimli $numpy$ nümerik dizilerine (array) çeviriniz.
c) $mV$ ve $d$ numpy dizilerini (a) şıkkında yazdığınız uzaklik_modulu isimli fonksiyona göndererek bu fonksiyonun döndüreceği mutlak görsel parlaklıkları $MV$ isimli bir numpy dizisine alınız.
d) Kelvin cinsinden $T$ dizisinde verilen sıcaklıkların 10 tabanında logaritmasını (numpy.log10 fonksiyonu ile) aldıktan sonra x ekseninde, $MV$ dizisindeki mutlak görsel parlaklıkları ise y ekseninde olacak şekilde çizdirerek bir HR diyagramı oluşturunuz. HR diyagramlarında geleneksel olarak sıcaklığın ($log T_{eff}$) büyükten küçüğe (ters sırada) verildiğine özen gösteriniz. Veri noktalarınızı kırmızı içi dolu dairlerle gösteriniz. Eksenlere ve grağinize uygun birer isim veriniz ve grafiğiniz üzerinde gösteriniz.