Python 基本語法與科學計算套件的使用: Python科學計算套件(一)

四堂課程大綱

  • 第一堂-Python 基礎(一):Python 簡介及環境建立、Python程式的編寫及執行、資料型態、基本輸入輸出、流程控制
  • 第二堂-Python 基礎(二):檔案讀寫、例外處理、函數、模組、物件導向
  • 第三堂-Python科學計算套件(一):Numpy、Matplotlib
  • 第四堂-Python科學計算套件(二):Scipy、Astropy

Numpy

  • Python 內建的list資料結構不適合數值運算
  • Python 內建的range()函數無法以浮點數來設定序列間距

In [1]:
period = [2.4, 5, 6.3, 4.1]
print(60 * period)
bh_mass = [4.3, 5.8, 9.5, 7.6]
MASS_SUN = 1.99 * 10 ** 30
print(MASS_SUN * bh_mass)


[2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1, 2.4, 5, 6.3, 4.1]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-b1efce155ec5> in <module>()
      3 bh_mass = [4.3, 5.8, 9.5, 7.6]
      4 MASS_SUN = 1.99 * 10 ** 30
----> 5 print(MASS_SUN * bh_mass)

TypeError: can't multiply sequence by non-int of type 'float'

In [2]:
time = list(range(1,10, 0.1))


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-4f9db0022dc3> in <module>()
----> 1 time = list(range(1,10, 0.1))

TypeError: 'float' object cannot be interpreted as an integer
  • 引入Numpy 套件

In [3]:
import numpy as np
  • 建立Numpy陣列

In [4]:
period = np.array([2.4, 5, 6.3, 4.1])
print(60 * period)
bh_mass = np.array([4.3, 5.8, 9.5, 7.6])
MASS_SUN = 1.99 * 10 ** 30
print(MASS_SUN * bh_mass)


[ 144.  300.  378.  246.]
[  8.55700000e+30   1.15420000e+31   1.89050000e+31   1.51240000e+31]

In [5]:
time = np.arange(1, 10, 0.1)
time2 = np.linspace(1, 10, 5)
init_value = np.zeros(10)
init_value2= np.ones(10)
print(time)
print(time2)
print(init_value)
print(init_value2)


[ 1.   1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2.   2.1  2.2  2.3  2.4
  2.5  2.6  2.7  2.8  2.9  3.   3.1  3.2  3.3  3.4  3.5  3.6  3.7  3.8  3.9
  4.   4.1  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9  5.   5.1  5.2  5.3  5.4
  5.5  5.6  5.7  5.8  5.9  6.   6.1  6.2  6.3  6.4  6.5  6.6  6.7  6.8  6.9
  7.   7.1  7.2  7.3  7.4  7.5  7.6  7.7  7.8  7.9  8.   8.1  8.2  8.3  8.4
  8.5  8.6  8.7  8.8  8.9  9.   9.1  9.2  9.3  9.4  9.5  9.6  9.7  9.8  9.9]
[  1.     3.25   5.5    7.75  10.  ]
[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
  • Numpy陣列的屬性

In [6]:
period2 = np.array([[2.4, 5, 6.3, 4.1], [4.2, 5.3, 1.2, 7.1]])
print(period2.ndim)
print(period2.shape)
print(period2.dtype)


2
(2, 4)
float64
  • Numpy陣列的操作

In [7]:
print(period2[0])
print(period2[1][1:-1])


[ 2.4  5.   6.3  4.1]
[ 5.3  1.2]

In [8]:
print(np.sort(period2[0]))
print(np.argsort(period2[0]))
print(np.argmax(period2[0]))
print(np.where(period2[0] > 4.5))
print(np.extract(period2[0] > 4.5, period2[0]))


[ 2.4  4.1  5.   6.3]
[0 3 1 2]
2
(array([1, 2]),)
[ 5.   6.3]

In [9]:
counts = 100 * np.sin(2 * np.pi * 1. / period2[0][1] * time) + 500
print(counts)


[ 595.10565163  598.22872507  599.80267284  599.80267284  598.22872507
  595.10565163  590.48270525  584.43279255  577.05132428  568.45471059
  558.77852523  548.17536741  536.81245527  524.86898872  512.53332336
  500.          487.46667664  475.13101128  463.18754473  451.82463259
  441.22147477  431.54528941  422.94867572  415.56720745  409.51729475
  404.89434837  401.77127493  400.19732716  400.19732716  401.77127493
  404.89434837  409.51729475  415.56720745  422.94867572  431.54528941
  441.22147477  451.82463259  463.18754473  475.13101128  487.46667664
  500.          512.53332336  524.86898872  536.81245527  548.17536741
  558.77852523  568.45471059  577.05132428  584.43279255  590.48270525
  595.10565163  598.22872507  599.80267284  599.80267284  598.22872507
  595.10565163  590.48270525  584.43279255  577.05132428  568.45471059
  558.77852523  548.17536741  536.81245527  524.86898872  512.53332336
  500.          487.46667664  475.13101128  463.18754473  451.82463259
  441.22147477  431.54528941  422.94867572  415.56720745  409.51729475
  404.89434837  401.77127493  400.19732716  400.19732716  401.77127493
  404.89434837  409.51729475  415.56720745  422.94867572  431.54528941
  441.22147477  451.82463259  463.18754473  475.13101128  487.46667664]
  • 亂數產生

In [10]:
import numpy.random as npr
print(npr.rand(5))
print(npr.randn(10))
print(npr.normal(5., 1., 10))


[ 0.00949426  0.39253669  0.58547868  0.13593649  0.79909709]
[-0.31904549 -0.4218687   1.77376265  0.68327387  0.82201527  0.58340251
 -0.67808942  0.49500332  0.29743951  0.22312296]
[ 6.17173667  4.45046351  6.26276051  5.61027644  7.19115054  5.18832971
  5.63769906  6.37128093  4.45809149  5.34242987]
  • 檔案輸出輸入

In [11]:
lc = np.array([time, counts])
np.savetxt('test.out', lc)
input_time, input_counts = np.loadtxt('test.out')

In [12]:
print(input_time)
print(input_counts)


[ 1.   1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2.   2.1  2.2  2.3  2.4
  2.5  2.6  2.7  2.8  2.9  3.   3.1  3.2  3.3  3.4  3.5  3.6  3.7  3.8  3.9
  4.   4.1  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9  5.   5.1  5.2  5.3  5.4
  5.5  5.6  5.7  5.8  5.9  6.   6.1  6.2  6.3  6.4  6.5  6.6  6.7  6.8  6.9
  7.   7.1  7.2  7.3  7.4  7.5  7.6  7.7  7.8  7.9  8.   8.1  8.2  8.3  8.4
  8.5  8.6  8.7  8.8  8.9  9.   9.1  9.2  9.3  9.4  9.5  9.6  9.7  9.8  9.9]
[ 595.10565163  598.22872507  599.80267284  599.80267284  598.22872507
  595.10565163  590.48270525  584.43279255  577.05132428  568.45471059
  558.77852523  548.17536741  536.81245527  524.86898872  512.53332336
  500.          487.46667664  475.13101128  463.18754473  451.82463259
  441.22147477  431.54528941  422.94867572  415.56720745  409.51729475
  404.89434837  401.77127493  400.19732716  400.19732716  401.77127493
  404.89434837  409.51729475  415.56720745  422.94867572  431.54528941
  441.22147477  451.82463259  463.18754473  475.13101128  487.46667664
  500.          512.53332336  524.86898872  536.81245527  548.17536741
  558.77852523  568.45471059  577.05132428  584.43279255  590.48270525
  595.10565163  598.22872507  599.80267284  599.80267284  598.22872507
  595.10565163  590.48270525  584.43279255  577.05132428  568.45471059
  558.77852523  548.17536741  536.81245527  524.86898872  512.53332336
  500.          487.46667664  475.13101128  463.18754473  451.82463259
  441.22147477  431.54528941  422.94867572  415.56720745  409.51729475
  404.89434837  401.77127493  400.19732716  400.19732716  401.77127493
  404.89434837  409.51729475  415.56720745  422.94867572  431.54528941
  441.22147477  451.82463259  463.18754473  475.13101128  487.46667664]

Matplotlib

  • 引入Matplotlib 套件

In [13]:
import matplotlib.pyplot as plt
%matplotlib inline
  • 基本樣式控制及文字標示

In [14]:
plt.plot(input_time, input_counts)
plt.xlabel('Time')
plt.ylabel('Counts')
plt.title('Light curve', fontsize=18)
plt.axis([1, 15, 350, 700])
plt.xticks([1, 5, 10])
plt.yticks([350, 500, 700])
#plt.show()  # 開啟圖片編輯視窗,並將圖顯示在該視窗中,透過該視窗可修改圖片、存檔



In [15]:
#plt.hold(True) # 保留目前的圖,以便重疊繪圖
plt.plot(input_time, input_counts-100, marker='o', color='green', linewidth=1)



In [16]:
plt.plot(input_time, input_counts+100, 'r*')
#plt.legend(('lc1', 'lc2', 'lc3'))
#plt.hold(False)


  • 把多張圖合併成一張圖

In [17]:
plt.subplot(211)
plt.plot(input_time, input_counts)
plt.subplot(212)
plt.plot(input_time, input_counts, '.m')
#plt.savefig('subplot.png')


  • 畫error bar

In [18]:
y_errors = 10 * npr.rand(len(input_time)) + 5
plt.plot(input_time, input_counts, 'k.')
plt.errorbar(input_time, input_counts, yerr=y_errors, fmt='r')


作業小專題

  • 修改上堂課的作業,將使用者輸入的參數 (伴星質量、軌道傾角、軌道周期、伴星的徑向速度) 各自存成Numpy陣列
  • 修改上堂課的作業,將程式所挑出的黑洞X-ray雙星相關資訊以Numpy陣列的型式輸出成一個檔案
  • 利用所挑出的黑洞X-ray雙星中的周期,模擬出其X-ray光變曲線觀測資料,並利用亂數陣列加入雜訊
  • 畫出你所模擬出的X-ray光變曲線觀測資料