汪群超 Chun-Chao Wang

Dept. of Statistics, National Taipei University, Taiwan

Lesson 1: 基本 Python

Objective:

  1. 學習進入 Python 計算的基礎與法與指令。
  2. 學習安裝套件、使用模組,譬如數學相關的 numpy 與統計計算相關的 scipy

Prerequisite:

  • 安裝 Python 與 Visual Studio Code (IDE) + Jupyter Notebook extensions 及其他客製化的 extensions。
  • 熟悉在 Jupyter Notebook 的環境中,寫 \LaTeX 數學式及其他文字表現。

範例 1: Python 的數字(number), 向量(vector) 與矩陣(array)

注意事項:

  1. 建立一個全新的目錄,並在 VS Code 中開啟,然後建立一個新檔案,檔名 lesson_1.py。輸入下列每個範例的每一行指令,執行並觀察結果。

  2. 在 VS Code 中執行副檔名為 py 的程式,執行的目標地點為下方的 terminal 視窗。而且除非使用 print(變數名稱),否則看不到執行結果。

  3. 另一個執行方式是借用 Jupyter Notebook 的延伸功能,將程式執行交給 Jupyter Notebook。 做法:按程式視窗右鍵,選擇「Run Current File in Interactive Window」。此時,除了在右邊新增一 Jupyter 視窗外,在下面的 terminal 視窗也會多出一個「Jupyter”Variables」的選項,裡面呈現目前為止出現過的變數名稱,及其資料形態與內容。方便觀察變數內容,不一定要用 print()。

  4. 下列的指令與語法的學習,採猜測的原則(從已經熟悉的某個語言)。從執行的結果去驗證。若還猜不到,可以上網查詢官網的說明。

  5. 變數名稱盡量能自我說明,長一點無所謂。

  6. Python 程式的格式有一定的樣子,可以使用 VS Code 的功能「Format Document」(按右鍵),程式碼會自動調整為較符合 coding 的原則。


    #%% 1. Numbers
    
    int_number = 1
    float_number = 1.0
    complex_number = 1 + 2j
    round_float = round(1234.5678, 2)
    str2int = int('213')
    
    print(round_float)
    
    # list and indexing
    
    number_list = [0, 1, 1, 2, 3, 5, 8]
    # the slicings use the zero-based indexing,
    # that includes the lower bound and omit the upper bound, e.g.
    print(number_list[3])  # indexing
    print(number_list[0:3])  # [n, m] : slicing from index n to the mth position of the list
    print(number_list[-1])  # the last one
    print(number_list[-3:])  # the last three
    
    list_list = [[1, 2, 3], [4, 5, 6]]  # list of list
    print(list_list)
    print(list_list[0:2])
    
    # Explain why "indexing" starts from 0
    
    a = [1, 2, 3, 4, 5, 6, 7]  # = np.arange(1, 8)
    low, high = 2, 4
    print(a[0:low] + a[low:high] + a[high:7])  
    
    


    注意事項:

    1. 開始使用 numpy 套件建立矩陣. 安裝方式(在下方 terminal 視窗): pip install numpy.

    2. 使用 np.size() and np.shape() 觀察矩陣或向量的大小。

    3. 練習向量與矩陣的索引(indexing)。

    # Vector and indexing
    
    import numpy as np
    
    a = np.array([1, 2, 3]) # a vector has no direction
    A = np.array([[1, 2, 3]]) # a 1 x 3 array that can be transposed
    a_T = a[:, np.newaxis] # a'
    A_T = A.T # A'
    C = np.array([1, 2, 3], ndmin = 2) # convert a to A
    print(np.size(a))  # number of elements
    print(np.shape(A_T))  # array dimension
    
    # Vector Indexing
    
    A = np.array([[1, 2, 3],[4, 5, 6]])
    print(A)
    print(A.shape) # shape() is a method of a numpy array
    print(A[1])
    print(A[1,:])
    print(A[:,1])
    print(A[:,[0,2]])
    

    矩陣堆疊與複製(Vectorization and Broadcasting)

    # vector concatenate
    a = np.array([1, 2, 3])
    b = np.array([4, 5, 6])
    c = np.concatenate((a, b), axis = 0) # flatten a, b
    d = np.append(a, b)
    e = np.hstack((a, b)) 
    F = np.vstack((a, b))
    g = np.r_[a, b]
    G = np.c_[a, b]
    H = (a, b)
    
    #matrix concatenate
    
    a = np.array([[1, 2, 3]])
    b = np.array([[4, 5, 6]])
    
    # Vertically, concatenate row-wisely 
    C = np.concatenate((a, b), axis = 0) 
    D = np.r_[a, b]
    E = np.vstack((a,b))
    
    # Horizontally, concatenate column-wisely
    F = np.concatenate((a.T, b.T), axis =1)
    G = np.hstack((a.T, b.T))
    H = np.c_[a.T, b.T]
    
    print(C)
    print(C.max())
    print(C.max(0)) # column max
    print(np.max(C, axis = 1)) # row max
    

    Note: The Difference Between a List and an Array in Python
    Arrays and lists are both used in Python to store data, but they don’t serve exactly the same purposes. They both can be used to store any data type (real numbers, strings, etc), and they both can be indexed and iterated through, but the similarities between the two don’t go much further. The main difference between a list and an array is the functions that you can perform to them. For example, you can divide an array by 3, and each number in the array will be divided by 3 and the result will be printed if you request it. If you try to divide a list by 3, Python will tell you that it can’t be done, and an error will be thrown. (citation: Quick Tip: The Difference Between a List and an Array in Python)

    tuple

    a_tuple = (0, 0) # ordered sequence
    also_a_tuple = 0, 0
    a_3d_tuple = (0, 1, 2) # (2,1,0) is different, however the list  [0,1,2] := [1,2,0]
    

    範例:Special matrices

    A = np.array([[1, 2, 3],[4, 5, 6]])
    a = A.flatten() # turn into vector
    b = A.flatten('F') # turn into vector column-wise
    A[A < 3] = 0
    
    c = [1, 2, 3, 4]
    C = np.tile(c,(5,1)) # = repmat in MATLAB
    d = np.reshape(C, (-1, 1)) # convert to Column vector
    print(C)
    print(d)
    print(C.flatten())
    
    Z = np.zeros((3,4))
    One =  np.ones((3,4))
    I = np.eye(3)
    D = np.diag(c) # D a diagonal matrix
    e = np.diag(I) # the diagonal of I
    

    範例:String and indexing

    #%% string & indexing
    
    s1 = 'a single quote string'
    s2 = "a double quote string"
    s3 = '''a triple quote string''' 
    
    print(type(s2))
    print(s3[0])
    print(s2[:4])
    print(s3)
    
    s4 = """
    Triple double quotes
    is usually used
    in multiple lines, such as documents
    """
    
    print(s4)
    
    # concatenate strings
    s5 = 'This is ' + s1
    print(s5)
    
    # string list
    str_list = ['r', 'g', 'b', 'k', 'y']
    print(str_list[1])
    
    # Dictionaries similar to structure in MATLAB
    meals = {'breakfast': 'sardines', 'lunch': 'salad', 'dinner': 'cake', 'cost':40}
    print(meals['breakfast'])
    print(meals['cost'])
    print('The meal costs {} dollars'.format(meals['cost']))  
    
    

    範例:Sequencial numbers

    import numpy as np
    
    x0 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    x1 = range(1, 10, 1)
    x2 = np.arange(1, 10, 1)  # integer
    x3 = np.linspace(1, 9, 9)  # float number
    
    x4 = np.arange(10)  # start from 0
    x5 = np.linspace(0, 100, 1000)
    # list and range type can not do math operations
    y1 = x2 + x3 + 1
    y2 = x2 ** 2 + x2 - 2
    y3 = x2 / x3
    

    範例:matrix operations



    Let X = \left[             \begin{array}{ccc}                 1 & 2  & 3 \\                 4 & 5  & 6 \\             \end{array} \right] \;\;, A = \left[             \begin{array}{ccc}                 1 & 1  & 1 \\                 2 & 4  & 6 \\                 5 & 7  & 6             \end{array} \right]\;\;\;, b = \left[             \begin{array}{c}                 1  \\                 2 \\                 3 \end{array} \right]

    仔細地計算下列每一個矩陣的運算。從結果去猜測指令的意思。

    1. X(1, 2)
    2. P(i,j) = X(i,j) * X(i,j) for 1 \leq i \leq 2, 1\leq j\leq 3
    3. Q(i,j) = X(i,j) / X(i,j) for 1 \leq i \leq 2, 1\leq j\leq 3
    4. R = XX^T
    5. total_sum =\sum_{i=1}^{2}\sum_{j=1}^{3} X(i,j)
    6. row_sum r_i=\sum_{j=1}^{3} X(i,j), 1\leq i \leq2
    7. col_sum c_j=\sum_{i=1}^{2} X(i,j), 1\leq i\leq 3
    8. x =A^{-1}b
    9. I = AA^{-1}
    10. A^2
    11. \sqrt{A}
    12. B = \left[             \begin{array}{c}                 A  \\                 b^T  \end{array} \right], i.e. add a new row vector after the last row of A.
    13. C = \left[             \begin{array}{cc}                 A & b \end{array} \right], i.e. add a new column vector after the last column of A.
    from numpy import linalg
    import numpy as np # numpy is a package
    import scipy.linalg as LA # scipy's linear algebra is better
    
    X = np.array([[1,2,3],[4,5,6]]) # a 2x3 matrix
    # check the information of X
    b = X.ndim
    S = X.shape
    s = X.size
    
    a = X[0, 1]
    P = X * X # element by element multiplication
    Q = X / X
    R = X @ X.T # XX'
    
    total_sum = X.sum() # X.mean()...
    row_sum = X.sum(axis = 1) # sum over each row
    # col_sum = X.sum(axis = 0) # sum over each column
    col_sum = np.sum(X, axis = 0) 
    
    A = np.array([[1, 1, 1],[2, 4, 6],[5, 7, 6]])
    b = np.array([1, 2, 3])
    x =  LA.inv(A) @ b  # Ax = b
    xsol = LA.solve(A, b) # Ax = b
    I = A @ LA.inv(A)
    
    A_square = linalg.matrix_power(A, 2) # nth power of a matrix
    A_square_root = LA.fractional_matrix_power(A, 0.5)
    
    B = np.vstack((A, b)) # 4 x 3
    C = np.hstack((A, b.reshape(3, 1))) # 3 x 4
    
    B_row = np.insert(A, 3, b, 0) # 3 is the position index; 0 is for row
    B_col = np.insert(A, 3, b, 1) # 3 is the position index; 1 is for column
    

    範例:Logical operations

    邏輯式運算非常好運,往往讓程式變得很簡潔。

    import numpy as np 
    
    x = np.array([1, 2, 5, 3, 2])
    x[x > 3] = 9 # replaced by 9; conditioned on x>3
    y = np.where(x > 3, 9, x)
    z = np.where(x >=3, 1, 0)
    
    a = 3
    if a > 1 and a < 5 :
        print('TRUE')
    else :
        print('FALSE')
    
    if a > 5 or a < 1 :
        print('OUTSIDE')
    else :
        print('INSIDE')
    
%d bloggers like this: