800100715151 Astronomide Veritabanları

Ders - 01 Jupyter ve Python'a 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

Dersin İçeriği (Preliminary Program)

  • Hafta 1. Python’la Programlamaya Giriş – I
  • Hafta 2. Python’la Programlamaya Giriş – II
  • Hafta 3. Python Betikleri Yardımıyla Astronomi Veritabanlarının Sorgulanması
  • Hafta 4. Astronomi Veritabanlarındaki Yığın Veri Üzerinde İşlemler
  • Hafta 5. Veritabanları Oluşturma ve Yönetme
  • Hafta 6. Python Betikleri Yardımıyla Astronomi Kataloglarının Sorgulanması
  • Hafta 7. Modern İstatistiksel Yöntemler, Tahmin ve Çıkarım–I (Descriptive Statistics)
  • Hafta 8. Modern İstatistiksel Yöntemler, Tahmin ve Çıkarım–II (Inference Statistics)
  • Hafta 9. Örnekleme Teknikleri (Monte Carlo Yöntemleri ve Nested Sampling)
  • Hafta 10. Veri Filtreleme, Bootstrapping, Random Fields, Diğer Nümerik Teknikler
  • Hafta 11. Bayesian Veri Analizi
  • Hafta 12. Astronomi Veritabanları ve Kataloglardan Alınan Veri Üzerinde Çıkarımlar
  • Hafta 13. Sınıflandırma
  • Hafta 14. Makine Öğrenmesine Giriş

Jupyter Defterleri

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.

Başa Dön

Jupyter'da Kod Çalıştırmak

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.

In [1]:
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)
1.2342

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 Metin Hücreleri

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!

Başa Dön

Jupyter'da Sihirli Sözcükler

Ç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.

In [2]:
% 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

In [3]:
%lsmagic
Out[3]:
Available line magics:
%alias  %alias_magic  %autocall  %automagic  %autosave  %bookmark  %cat  %cd  %clear  %colors  %config  %connect_info  %cp  %debug  %dhist  %dirs  %doctest_mode  %ed  %edit  %env  %gui  %hist  %history  %killbgscripts  %ldir  %less  %lf  %lk  %ll  %load  %load_ext  %loadpy  %logoff  %logon  %logstart  %logstate  %logstop  %ls  %lsmagic  %lx  %macro  %magic  %man  %matplotlib  %mkdir  %more  %mv  %notebook  %page  %pastebin  %pdb  %pdef  %pdoc  %pfile  %pinfo  %pinfo2  %popd  %pprint  %precision  %profile  %prun  %psearch  %psource  %pushd  %pwd  %pycat  %pylab  %qtconsole  %quickref  %recall  %rehashx  %reload_ext  %rep  %rerun  %reset  %reset_selective  %rm  %rmdir  %run  %save  %sc  %set_env  %store  %sx  %system  %tb  %time  %timeit  %unalias  %unload_ext  %who  %who_ls  %whos  %xdel  %xmode

Available cell magics:
%%!  %%HTML  %%SVG  %%bash  %%capture  %%debug  %%file  %%html  %%javascript  %%js  %%latex  %%markdown  %%perl  %%prun  %%pypy  %%python  %%python2  %%python3  %%ruby  %%script  %%sh  %%svg  %%sx  %%system  %%time  %%timeit  %%writefile

Automagic is ON, % prefix IS NOT needed for line magics.

Jupyter'da Hücre Silmek ve Eklemek

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, tuşunu iki kez arkaya basmak suretiyle hücre silmek için kullanabilirsiniz. Bu işlemler için bulunduğunuz hücrenin aktif olmayıp (yeşil çerçeve) (edit mode), sadece seçilii (mavi çerçeve) emin olunuz. Aktif ise ESC tuşuna basarak hücreyi seçili duruma getirebilirsiniz.

Jupyter'da Yardım Seçenekleri

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.

  1. iPython'ın (Jupyter iPython defer yapısı üzerine kurulmuştur) tanımlı (built-in) yardım fonksiyonu (help)
In [4]:
help(len)
Help on built-in function len in module builtins:

len(obj, /)
    Return the number of items in a container.

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.

In [5]:
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.

In [6]:
L = ['1', 3.14, 2]
help(L.insert)
Help on built-in function insert:

insert(...) method of builtins.list instance
    L.insert(index, object) -- insert object before index

In [7]:
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.

In [8]:
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)
Yaricapi 5 birim olan bir dairenin alani 78.5398 birimkare, cevresi 31.4159 birimdir
-----------------------------------------
Daire fonksiyonu dokumantasyon blogu:
-----------------------------------------
Help on function daire in module __main__:

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

Fonksiyonun kaynak koduna ulaşmak için fonksiyon adını takiben ?? kullanılır.

In [9]:
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.

In [10]:
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.

In [11]:
# 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.

In [12]:
# 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.

In [13]:
*Warning?

Sihirli Sözcükler Konusunda Yardım Alma:

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.

In [14]:
%timeit?

Herhangi bir sihirli sözcükle ilgili dokümantasyona sözcüğü yazıp Enter'a basarak erişebilirsiniz.

In [15]:
%run
%run:
 Run the named file inside IPython as a program.

Usage::

  %run [-n -i -e -G]
       [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
       ( -m mod | file ) [args]

Parameters after the filename are passed as command-line arguments to
the program (put in sys.argv). Then, control returns to IPython's
prompt.

This is similar to running at a system prompt ``python file args``,
but with the advantage of giving you IPython's tracebacks, and of
loading all variables into your interactive namespace for further use
(unless -p is used, see below).

The file is executed in a namespace initially consisting only of
``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
sees its environment as if it were being run as a stand-alone program
(except for sharing global objects such as previously imported
modules). But after execution, the IPython interactive namespace gets
updated with all variables defined in the program (except for __name__
and sys.argv). This allows for very convenient loading of code for
interactive work, while giving each program a 'clean sheet' to run in.

Arguments are expanded using shell-like glob match.  Patterns
'*', '?', '[seq]' and '[!seq]' can be used.  Additionally,
tilde '~' will be expanded into user's home directory.  Unlike
real shells, quotation does not suppress expansions.  Use
*two* back slashes (e.g. ``\\*``) to suppress expansions.
To completely disable these expansions, you can use -G flag.

Options:

-n
  __name__ is NOT set to '__main__', but to the running file's name
  without extension (as python does under import).  This allows running
  scripts and reloading the definitions in them without calling code
  protected by an ``if __name__ == "__main__"`` clause.

-i
  run the file in IPython's namespace instead of an empty one. This
  is useful if you are experimenting with code written in a text editor
  which depends on variables defined interactively.

-e
  ignore sys.exit() calls or SystemExit exceptions in the script
  being run.  This is particularly useful if IPython is being used to
  run unittests, which always exit with a sys.exit() call.  In such
  cases you are interested in the output of the test results, not in
  seeing a traceback of the unittest module.

-t
  print timing information at the end of the run.  IPython will give
  you an estimated CPU time consumption for your script, which under
  Unix uses the resource module to avoid the wraparound problems of
  time.clock().  Under Unix, an estimate of time spent on system tasks
  is also given (for Windows platforms this is reported as 0.0).

If -t is given, an additional ``-N<N>`` option can be given, where <N>
must be an integer indicating how many times you want the script to
run.  The final timing report will include total and per run results.

For example (testing the script uniq_stable.py)::

    In [1]: run -t uniq_stable

    IPython CPU timings (estimated):
      User  :    0.19597 s.
      System:        0.0 s.

    In [2]: run -t -N5 uniq_stable

    IPython CPU timings (estimated):
    Total runs performed: 5
      Times :      Total       Per run
      User  :   0.910862 s,  0.1821724 s.
      System:        0.0 s,        0.0 s.

-d
  run your program under the control of pdb, the Python debugger.
  This allows you to execute your program step by step, watch variables,
  etc.  Internally, what IPython does is similar to calling::

      pdb.run('execfile("YOURFILENAME")')

  with a breakpoint set on line 1 of your file.  You can change the line
  number for this automatic breakpoint to be <N> by using the -bN option
  (where N must be an integer). For example::

      %run -d -b40 myscript

  will set the first breakpoint at line 40 in myscript.py.  Note that
  the first breakpoint must be set on a line which actually does
  something (not a comment or docstring) for it to stop execution.

  Or you can specify a breakpoint in a different file::

      %run -d -b myotherfile.py:20 myscript

  When the pdb debugger starts, you will see a (Pdb) prompt.  You must
  first enter 'c' (without quotes) to start execution up to the first
  breakpoint.

  Entering 'help' gives information about the use of the debugger.  You
  can easily see pdb's full documentation with "import pdb;pdb.help()"
  at a prompt.

-p
  run program under the control of the Python profiler module (which
  prints a detailed report of execution times, function calls, etc).

  You can pass other options after -p which affect the behavior of the
  profiler itself. See the docs for %prun for details.

  In this mode, the program's variables do NOT propagate back to the
  IPython interactive namespace (because they remain in the namespace
  where the profiler executes them).

  Internally this triggers a call to %prun, see its documentation for
  details on the options available specifically for profiling.

There is one special usage for which the text above doesn't apply:
if the filename ends with .ipy[nb], the file is run as ipython script,
just as if the commands were written on IPython prompt.

-m
  specify module name to load instead of script path. Similar to
  the -m option for the python interpreter. Use this option last if you
  want to combine with other %run options. Unlike the python interpreter
  only source modules are allowed no .pyc or .pyo files.
  For example::

      %run -m example

  will run the example module.

-G
  disable shell-like glob expansion of arguments.
/usr/local/lib/python3.5/dist-packages/IPython/core/magics/execution.py:649: UserWarning: you must provide at least a filename.
  warn('you must provide at least a filename.')

Jupyter ve Çekirdekler

Ç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.

In [16]:
print("merhaba, stdout")
merhaba, stdout
In [17]:
3 + 5
Out[17]:
8
In [18]:
np.array([1,2,3])
Out[18]:
array([1, 2, 3])

Kod Çıktılarıyla İşlemler

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.

In [19]:
import time, sys
for i in range(5):
    print(i)
    time.sleep(0.8)
0
1
2
3
4

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.

In [20]:
for i in range(60):
    print(i)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

Eğer kodun çıktsı çok uzunsa tarayıcı bunun için bir kaydırma çubuğunu otomatik olarak sağlar.

In [21]:
from math import pi
for r in range(500):
    print(2*pi*r)
0.0
6.283185307179586
12.566370614359172
18.84955592153876
25.132741228718345
31.41592653589793
37.69911184307752
43.982297150257104
50.26548245743669
56.548667764616276
62.83185307179586
69.11503837897544
75.39822368615503
81.68140899333463
87.96459430051421
94.24777960769379
100.53096491487338
106.81415022205297
113.09733552923255
119.38052083641213
125.66370614359172
131.94689145077132
138.23007675795088
144.51326206513048
150.79644737231007
157.07963267948966
163.36281798666926
169.64600329384882
175.92918860102841
182.212373908208
188.49555921538757
194.77874452256717
201.06192982974676
207.34511513692635
213.62830044410595
219.9114857512855
226.1946710584651
232.4778563656447
238.76104167282426
245.04422698000386
251.32741228718345
257.610597594363
263.89378290154264
270.1769682087222
276.46015351590177
282.7433388230814
289.02652413026095
295.3097094374406
301.59289474462014
307.8760800517997
314.1592653589793
320.4424506661589
326.7256359733385
333.0088212805181
339.29200658769764
345.57519189487726
351.85837720205683
358.1415625092364
364.424747816416
370.7079331235956
376.99111843077515
383.27430373795477
389.55748904513433
395.84067435231395
402.1238596594935
408.4070449666731
414.6902302738527
420.97341558103227
427.2566008882119
433.53978619539146
439.822971502571
446.10615680975064
452.3893421169302
458.6725274241098
464.9557127312894
471.23889803846896
477.5220833456485
483.80526865282815
490.0884539600077
496.37163926718733
502.6548245743669
508.93800988154646
515.221195188726
521.5043804959057
527.7875658030853
534.0707511102648
540.3539364174444
546.637121724624
552.9203070318035
559.2034923389832
565.4866776461628
571.7698629533423
578.0530482605219
584.3362335677015
590.6194188748811
596.9026041820607
603.1857894892403
609.4689747964198
615.7521601035994
622.0353454107791
628.3185307179587
634.6017160251382
640.8849013323178
647.1680866394973
653.451271946677
659.7344572538566
666.0176425610362
672.3008278682157
678.5840131753953
684.8671984825748
691.1503837897545
697.4335690969341
703.7167544041137
709.9999397112932
716.2831250184728
722.5663103256525
728.849495632832
735.1326809400116
741.4158662471912
747.6990515543707
753.9822368615503
760.26542216873
766.5486074759095
772.8317927830891
779.1149780902687
785.3981633974482
791.6813487046279
797.9645340118075
804.247719318987
810.5309046261666
816.8140899333462
823.0972752405258
829.3804605477054
835.663645854885
841.9468311620645
848.2300164692441
854.5132017764238
860.7963870836033
867.0795723907829
873.3627576979625
879.645943005142
885.9291283123216
892.2123136195013
898.4954989266809
904.7786842338604
911.06186954104
917.3450548482195
923.6282401553992
929.9114254625788
936.1946107697584
942.4777960769379
948.7609813841175
955.044166691297
961.3273519984767
967.6105373056563
973.8937226128359
980.1769079200154
986.460093227195
992.7432785343747
999.0264638415542
1005.3096491487338
1011.5928344559134
1017.8760197630929
1024.1592050702725
1030.442390377452
1036.7255756846316
1043.0087609918114
1049.291946298991
1055.5751316061705
1061.85831691335
1068.1415022205297
1074.4246875277092
1080.7078728348888
1086.9910581420684
1093.274243449248
1099.5574287564275
1105.840614063607
1112.1237993707869
1118.4069846779664
1124.690169985146
1130.9733552923256
1137.2565405995051
1143.5397259066847
1149.8229112138642
1156.1060965210438
1162.3892818282234
1168.672467135403
1174.9556524425827
1181.2388377497623
1187.5220230569419
1193.8052083641214
1200.088393671301
1206.3715789784806
1212.6547642856601
1218.9379495928397
1225.2211349000193
1231.5043202071988
1237.7875055143784
1244.0706908215582
1250.3538761287377
1256.6370614359173
1262.9202467430969
1269.2034320502764
1275.486617357456
1281.7698026646356
1288.0529879718151
1294.3361732789947
1300.6193585861743
1306.902543893354
1313.1857292005336
1319.4689145077132
1325.7520998148927
1332.0352851220723
1338.3184704292519
1344.6016557364314
1350.884841043611
1357.1680263507906
1363.4512116579701
1369.7343969651497
1376.0175822723295
1382.300767579509
1388.5839528866886
1394.8671381938682
1401.1503235010478
1407.4335088082273
1413.7166941154069
1419.9998794225864
1426.283064729766
1432.5662500369456
1438.8494353441251
1445.132620651305
1451.4158059584845
1457.698991265664
1463.9821765728436
1470.2653618800232
1476.5485471872028
1482.8317324943823
1489.114917801562
1495.3981031087415
1501.681288415921
1507.9644737231006
1514.2476590302804
1520.53084433746
1526.8140296446395
1533.097214951819
1539.3804002589986
1545.6635855661782
1551.9467708733578
1558.2299561805373
1564.513141487717
1570.7963267948965
1577.0795121020763
1583.3626974092558
1589.6458827164354
1595.929068023615
1602.2122533307945
1608.495438637974
1614.7786239451536
1621.0618092523332
1627.3449945595128
1633.6281798666923
1639.911365173872
1646.1945504810517
1652.4777357882313
1658.7609210954108
1665.0441064025904
1671.32729170977
1677.6104770169495
1683.893662324129
1690.1768476313086
1696.4600329384882
1702.7432182456678
1709.0264035528476
1715.3095888600271
1721.5927741672067
1727.8759594743863
1734.1591447815658
1740.4423300887454
1746.725515395925
1753.0087007031045
1759.291886010284
1765.5750713174637
1771.8582566246432
1778.141441931823
1784.4246272390026
1790.7078125461821
1796.9909978533617
1803.2741831605413
1809.5573684677208
1815.8405537749004
1822.12373908208
1828.4069243892595
1834.690109696439
1840.9732950036187
1847.2564803107985
1853.539665617978
1859.8228509251576
1866.1060362323371
1872.3892215395167
1878.6724068466963
1884.9555921538758
1891.2387774610554
1897.521962768235
1903.8051480754145
1910.088333382594
1916.371518689774
1922.6547039969535
1928.937889304133
1935.2210746113126
1941.5042599184922
1947.7874452256717
1954.0706305328513
1960.3538158400308
1966.6370011472104
1972.92018645439
1979.2033717615698
1985.4865570687493
1991.769742375929
1998.0529276831085
2004.336112990288
2010.6192982974676
2016.9024836046472
2023.1856689118267
2029.4688542190063
2035.7520395261859
2042.0352248333654
2048.318410140545
2054.601595447725
2060.884780754904
2067.167966062084
2073.4511513692632
2079.734336676443
2086.017521983623
2092.300707290802
2098.583892597982
2104.8670779051613
2111.150263212341
2117.4334485195204
2123.7166338267
2129.9998191338796
2136.2830044410593
2142.5661897482387
2148.8493750554185
2155.1325603625983
2161.4157456697776
2167.6989309769574
2173.9821162841367
2180.2653015913165
2186.548486898496
2192.8316722056757
2199.114857512855
2205.398042820035
2211.681228127214
2217.964413434394
2224.2475987415737
2230.530784048753
2236.813969355933
2243.097154663112
2249.380339970292
2255.6635252774713
2261.946710584651
2268.2298958918304
2274.5130811990102
2280.79626650619
2287.0794518133694
2293.362637120549
2299.6458224277285
2305.9290077349083
2312.2121930420876
2318.4953783492674
2324.7785636564467
2331.0617489636265
2337.344934270806
2343.6281195779857
2349.9113048851655
2356.194490192345
2362.4776754995246
2368.760860806704
2375.0440461138837
2381.327231421063
2387.610416728243
2393.893602035422
2400.176787342602
2406.4599726497813
2412.743157956961
2419.026343264141
2425.3095285713202
2431.5927138785
2437.8758991856794
2444.159084492859
2450.4422698000385
2456.7254551072183
2463.0086404143976
2469.2918257215774
2475.5750110287568
2481.8581963359366
2488.1413816431163
2494.4245669502957
2500.7077522574755
2506.990937564655
2513.2741228718346
2519.557308179014
2525.8404934861937
2532.123678793373
2538.406864100553
2544.690049407732
2550.973234714912
2557.256420022092
2563.539605329271
2569.822790636451
2576.1059759436303
2582.38916125081
2588.6723465579894
2594.955531865169
2601.2387171723485
2607.5219024795283
2613.805087786708
2620.0882730938874
2626.3714584010672
2632.6546437082466
2638.9378290154264
2645.2210143226057
2651.5041996297855
2657.787384936965
2664.0705702441446
2670.353755551324
2676.6369408585037
2682.9201261656835
2689.203311472863
2695.4864967800427
2701.769682087222
2708.052867394402
2714.336052701581
2720.619238008761
2726.9024233159403
2733.18560862312
2739.4687939302994
2745.751979237479
2752.035164544659
2758.3183498518383
2764.601535159018
2770.8847204661975
2777.1679057733772
2783.4510910805566
2789.7342763877364
2796.0174616949157
2802.3006470020955
2808.583832309275
2814.8670176164546
2821.1502029236344
2827.4333882308138
2833.7165735379936
2839.999758845173
2846.2829441523527
2852.566129459532
2858.849314766712
2865.132500073891
2871.415685381071
2877.6988706882503
2883.98205599543
2890.26524130261
2896.548426609789
2902.831611916969
2909.1147972241483
2915.397982531328
2921.6811678385075
2927.9643531456873
2934.2475384528666
2940.5307237600464
2946.8139090672257
2953.0970943744055
2959.3802796815853
2965.6634649887646
2971.9466502959444
2978.229835603124
2984.5130209103036
2990.796206217483
2997.0793915246627
3003.362576831842
3009.645762139022
3015.928947446201
3022.212132753381
3028.4953180605607
3034.77850336774
3041.06168867492
3047.344873982099
3053.628059289279
3059.9112445964583
3066.194429903638
3072.4776152108175
3078.7608005179973
3085.043985825177
3091.3271711323564
3097.610356439536
3103.8935417467155
3110.1767270538953
3116.4599123610747
3122.7430976682544
3129.026282975434
3135.3094682826136
**Önemli Not**: Bir Jupyter defteri üzerinde çalışırken daha önce çalıştırdığınız tüm hücrelerdeki tüm değişkenler, tanımladığınız fonksiyonlar, yaptığınız tüm değişiklikler vs. hafızada tutulur ve IPython tarafından bilinir. Tüm defterin başına çıkıp, defterin daha alt kısmında tanımlı bir fonksiyona bir değişken gönderseniz dahi çalışacaktır. Zira o fonksiyon IPython tarafından bilinmektedir. Her şeyi sıfırlamak istemeniz durumunda Kernel menüsünün altındaki seçenenkleri (Restart, Restart & Clear Output, Restart & Run All) kullanabilirsiniz.

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.

In [22]:
print(In[1])
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)
In [23]:
x = 2.0
y = 2*x**2 - 2*x + 4
y
Out[23]:
8.0
In [24]:
print(Out[23]) # Sizde 25. output olmayabilir, dogru sayiyla calistiriniz
8.0
In [25]:
Out[23]*3*x**2
Out[25]:
96.0

print() son çıktıyı, print() bir öncekini, and print() ondan öncekini ... verir

In [26]:
print(_)
print(__)
96.0
8.0

Out[25] için bir kısa yol _25 yazmaktır.

In [27]:
import math
_25-math.sin(math.pi/2)
Out[27]:
95.0

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.

In [28]:
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.

In [30]:
Out[27] # Bir önceki kod satiri hangi sayiya sahipse onu kullaniniz
Out[30]:
95.0

%history ilgili Jupyter defterinde çalıştırılmış kod bloklarının numaralarını almak için kullanılabilir.

In [ ]:
%history -n 20-23

Python, Numpy ve Scipy'a Giriş

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'a Giriş

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.

Dizi Oluşturma İşlemleri

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.

In [ ]:
# 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)
In [ ]:
# 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.

In [ ]:
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.

In [ ]:
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.

In [ ]:
loga = np.logspace(1,5,5)
print("loga : ", loga)

Bir fonksiyona dayalı olarak bir numpy dizisi oluşturmak için np.fromfunction fonksiyonunu kullanabilirsiniz.

In [ ]:
dizi = np.fromfunction(lambda i, j: i * j, (4, 4), dtype=int)
print(dizi)

İndeksleme ve Dizi Dilimleme

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ı

In [ ]:
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.

In [ ]:
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.

In [68]:
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)
a[a < 0] --> [-4. -3. -2. -1.]
a[a < 0] = a.max() --> [ 5.  5.  5.  5.  0.  1.  2.  3.  4.  5.]
a[[1,6,7]] = 10 --> [  5.  10.   5.   5.   0.   1.  10.  10.   4.   5.]
a[a == 10] = [10, 20, 30] --> [  5.  10.   5.   5.   0.   1.  20.  30.   4.   5.]
[ True  True  True  True False False  True  True  True  True]

Çok Boyutlu Dizilerde İndeksleme ve Dilimleme

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.

In [32]:
a = np.arange(15).reshape(3,5)
print("a: \n", a)
a: 
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

Dizi içinde belli bir elemanın yerini belirlemek (indekslemek) için aşağıdaki yazım kurallarından herhangi biri kullanılabilir.

In [45]:
print("a[1,2]: ", a[1,2])
print("a[1][2]: ", a[1][2])
a[1,2]:  7
a[1][2]:  7

Benzer bir mantığı takip ederek dilimleme de yapabilirsiniz.

In [36]:
# 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[0:2,1:4]: 
 [[1 2 3]
 [6 7 8]]
In [39]:
# a dizisinin bastan sona birer atlayarak tum satirlari
# ve son satir haric tum sutunlari
print("a[::2,:-1] \n", a[::2,:-1]) 
a[::2,:-1] 
 [[ 0  1  2  3]
 [10 11 12 13]]

Herhangi bir sütuna ulaşmaya çalışırken numpy'ın satırı öncelediği akılda tutulmalıdır.

In [46]:
print("a[:,2]: ", a[:,2])
a[:,2]:  [ 2  7 12]

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.

In [56]:
# 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
1.satir: [0 1 2 3 4]
2.satir: [5 6 7 8 9]
3.satir: [10 11 12 13 14]
0.sutun: [ 0  5 10]
1.sutun: [ 1  6 11]
2.sutun: [ 2  7 12]
3.sutun: [ 3  8 13]
4.sutun: [ 4  9 14]

Temel numpy metotları

Bir numpy dizisi üzerine tanılanmış pek çok metot bulunmakla birlikte sıklıkla kullanılanları aşağıda örneklenmiştir.

In [ ]:
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.

In [ ]:
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.

In [ ]:
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.

In [ ]:
i4 = np.eye(4)
print("4x4 birim matris formunda dizi: \n", i4)

Dizi Kopyalama

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.

In [57]:
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)
a:  [ 0.    0.25  0.5   0.75  1.    1.25  1.5   1.75  2.    2.25  2.5   2.75
  3.    3.25  3.5   3.75  4.  ]
b:  [ 0.    0.25  0.5   0.75  1.    1.25  1.5   1.75  2.    2.25  2.5   2.75
  3.    3.25  3.5   3.75  4.  ]
Degisiklik sonrasi a:  [   0.      0.25  100.      0.75    1.      1.25    1.5     1.75    2.
    2.25    2.5     2.75    3.      3.25    3.5     3.75    4.  ]
Degisiklik sonrasi b:  [   0.      0.25  100.      0.75    1.      1.25    1.5     1.75    2.
    2.25    2.5     2.75    3.      3.25    3.5     3.75    4.  ]

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.

In [60]:
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)
1. dizi: 
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]]
2. dizi: 
 [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]
2. dizideki degisiklik sonrasi 1. dizi: 
 [[ 0 -1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]]
2. dizideki degisiklik sonrasi 2. dizi: 
 [ 0 -1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]
In [61]:
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)
a:  [ 0.   0.5  1.   1.5  2. ]
b:  [ 0.   0.5  1.   1.5  2. ]
a:  [ 0.   0.5  1.   1.5  2. ]
b:  [    0.   -100.  -1000.      1.5     2. ]

İ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.

In [66]:
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)
a:  [ 1.   1.6  2.2  2.8  3.4  4. ]
c:  [ 1.   1.6  2.2  2.8  3.4  4. ]
c = a?: False
c:  [[ 1.   1.6  2.2]
 [ 2.8  3.4  4. ]]
True
False
True

Diziler Üzerinde İşlemler

Python'da, toplama, bir sabitle çarpma gibi bazı işlemler numpy dizileri üzerinde doğrudan uygulanabilir.

In [ ]:
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.

In [ ]:
print("a^2: \n", a**2)

Ancak matris çarpması da numpy üzerinde yapılabilir ve bunun için @ operatörü kullanılır.

In [ ]:
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)
Görüldüğü üzere a: 5x4 bir dizi, b: 4x5 dizi olduğundan a.b: 5x5 bir dizidir.

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.

In [ ]:
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()

Alıştırmalar (numpy)

  1. 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.

  2. 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]]
  3. 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
  4. 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.

  5. 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.

  6. 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}$),
  • Her bir elemanının ortalamadan farkını $a - \bar{a}$,
  • Bu farkların kareleri toplamını ($\Sigma (a - \bar{a})^2$),
  • Bu toplamın a dizisinin eleman sayısını bölümünü,
  • ve son olarak bu bölümün karekökü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.

Ödev 1

Teslim Tarihi: 17 Şubat 2020, Çarşamba 09:30

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.