--- title: python讀書會(六) tags: python讀書會 notes: 爬蟲、神經網路、DL、%d、字串的速度文檔、比較速度實驗、unicode、輸入字元、array、作圖... --- {%hackmd @themes/orangeheart %} ## 6.0 回顧... 1. 模組: math, random, python內建函數(這個還沒完成,請替我完成它,順便熟悉一下這些功能)... 2. 介紹tuple、list和set的特性 3. 刷題(虧數、盈數、完全數) :::info :bird:**complement** list還有以下這些寫法 : ```python list1 = [2 ** x for x in range(10) if x > 5] list2 = [x + y for x in ['Python ', 'C '] for y in ['Language', 'Programming']] ``` ::: ## 6.1 數據類型 #### 6.1.1 set set當中的資料是無序的,也就是說,你無法利用位置索引去找到其中的元素。 set裡面可以有tuple,卻不允許有list,~~而且抗議無效~~。 - [ ] 程式碼 6.1.1a ```python= set1 = {1,2,3,4,5} set2 = {5,5,5,5,5,5,1,4,3,4,2,1} print(set1 == set2) ``` - [ ] 程式碼 6.1.1b ```python= #add:加入一個元素 #update:加入多個元素 set3 = {1,3} set3.add("Hello, world!") print(set3) set3.update([(3, 2, chr(88)), 3, True]) print(set3) set3.update([4, 5], {1, 6, 8}) print(set3) ``` - [ ] 程式碼 6.1.1c ```python= #有幾種移除set元素的函數,他們的差異如下: set4 = {1, 3, 4, 5, 6} print(set4) set4.discard(4) print(set4) set4.remove(6) print(set4) set4.discard(2) print(set4) set4.remove(2)#會error ###############我是分隔線############### set5 = set("HelloWorld")#將文字弄成集合會有不可思議的效果 print(set5) print(set5.pop())#隨機刪除一個物件,因為set沒有索引 set5.pop() print(set5) set5.clear()#全部刪掉 print(set5) ``` 你可以將set想成是數學裡面的集合,在python中運用下列符號來表示聯集(union)、交集(intersection)、差集(difference)、對稱差集(symmetric difference)。 ![](https://i.imgur.com/G1z4nSL.png =400x) - [ ] 程式碼 6.1.1d ```python= A = {1, 2, 3, 4, 5} B = {4, 5, 6, 7, 8} #Union print(A | B)#記住這個符號,shift+[Enter上面那個鍵] print(A.union(B))#這樣表示也可以 #Intersection print(A & B) print(A.intersection(B)) #Difference print(A - B) print(A.difference(B)) #Symmetric Difference print(A ^ B) print(A.symmetric_difference(B)) ``` - [ ] 程式碼 6.1.1e ```python= #set.fn()才有效喔 add() update() clear() difference() discard() intersection() pop() remove() symmetric_difference() union() copy() difference_update() intersection_update() isdisjoint() issubset() issuperset() symmetric_difference_update() ##############我是分隔線############# all() any() enumerate() len() max() min() sorted()#回傳一個list!! sum() ``` 在迭代中,除了range()、list、string以外,其實也可以使用set來進行迴圈。 ```python for letter in set("apple"): print(letter) ``` 數據型態中,我們有可變列表(list),也有不可變列表(tuple),還有可變集合(set),其實有個新的**不可變集合(frozenset)**,可以嘗試玩玩看。 ##### 6.1.2 dictionary Dictionary型態的數據長這樣: ```dict = {key1:value1, key2:value2, key3:value3}``` - [ ] 程式碼 6.1.2a ```python= #也可以嘗試以這樣的方式創建dictionary my_dict = dict([(1,'apple'), (2,'ball')]) print(my_dict) ``` 當你創建一個```{}```時,回傳給電腦的資料類型會是```dictionary```,而不是```set```。 - [ ] 程式碼 6.1.2b ```python= a = {} print(type(a)) ``` 要從dict型態數據中提取資料只能輸入```key```以獲得```value```,```key```就像list的index,```value```則像是list的data。 - [ ] 程式碼 6.1.2c ```python= # get vs [] for retrieving elements dict1 = {'name': 'Jack', 'age': 26} print(dict1.get('name')) print(dict1['name'])#[]和.get()幾乎相同 print(dict1.get('Jack')) print(dict1['Jack'])#.get()只會回傳None,但[]容易error ``` - [ ] 程式碼 6.1.2d ```python= #更改dict資料 dict1['age'] = 27#修改 print(dict1) dict1['address'] = 'Downtown'#新增 print(dict1) ######################################## squares = {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} print(squares.pop(4))#.pop(key),這邊會回傳value print(squares) print(squares.popitem())#隨機刪除一個 print(squares) squares.clear()#所有資料都刪除 print(squares) del squares#error print(squares) ``` - [ ] 程式碼 6.1.2e ```python= clear() copy() fromkeys(seq[, v]) get(key[,d]) items() keys() pop(key[,d]) popitem() setdefault(key[,d]) update([other]) values() ``` - [ ] 程式碼 6.1.2f ```python= score = {}.fromkeys(['Math', 'English', 'Science'], 0) print(score) for item in score.items(): print(item)#在用程式執行之前,先想想看會輸出什麼 print(list(sorted(score.keys())))#在用程式執行之前,先想想看會輸出什麼 ``` **進階一點的~:fire:** 以下這些程式碼的技巧,可以嘗試用在list、tuple、set上,如果想要更加理解這些嵌套循環,可以查詢"dictionary comprehension"來獲得所求資源。 - [ ] 程式碼 6.1.2g ```python= #❤️進階一點的 odd_squares = {x: x*x for x in range(11) if x % 2 == 1} #更輕鬆創建dict print(odd_squares) #✨再進階一點的 dictionary = {k1: {k2: k1 * k2 for k2 in range(1, 6)} for k1 in range(2, 5)} print(dictionary) ``` ## 6.2 Numpy, Matplotlib 第一件事情,請檢查一下你的電腦python有沒有numpy、matplotlib套件。 如果沒有,那就先去cmd上面```pip install numpy ^ pip install matplotlib```。 **[Numpy](https://numpy.org/)** 適用於操作有關陣列(array)、矩陣(matrix, matrices)的運算;比如說向量(vector)、線性代數(linear algebra)、傅立葉轉換(Fourier transforms)...。在處理數據時,它可以比list快50倍,因為資料是被連續儲存的,編寫語言部分是用 Python 編寫的,但大多數需要快速計算的部分是用C或C++編寫的(C語言學起來!!)。 ![](https://i.imgur.com/zymK7iu.png) **[Matplotlib](https://matplotlib.org/)** 用於在Python中創建靜態、動畫和交互式可視化,搭配numpy使用,效果相得益彰。 ![](https://i.imgur.com/ckmkA2W.png =500x) #### 6.2.1 Numpy.Array 現在就可以將之前學過的有關python的指令拿出來舉一反三!! - [ ] 程式碼 6.2.1a ```python= import numpy arr = numpy.array([1, 2, 3, 4, 5])#list型態的數組,改成tuple和set試試看 print(arr) print(type(arr)) ``` **array維度:** 嵌套陣列(nested array),陣列裡面還有陣列,以下可以創建高維度陣列。 ![](https://i.imgur.com/9JGfMfh.png =650x) - [ ] 程式碼 6.2.1b ```python= #0-dimension arr0d = np.array(42) #1-dimension arr1d = np.array([1, 2, 3, 4, 5]) #2-dimension arr2d = np.array([[1, 2, 3], [4, 5, 6]]) #3-dimension arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]) #檢查維度(ndim) print(arr0d.ndim) print(arr1d.ndim) print(arr2d.ndim) print(arr3d.ndim) #創建一個高維陣列(5-dimension) arr = np.array([1, 2, 3, 4], ndmin = 5) ``` 在Numpy這個章節當中,可以對於list和array進行大量比較,它們都可以建立多維陣列,其他的操作是否都夠通用?我們所知的是numpy.array運算速度遠快於list。 - [ ] 程式碼 6.2.1c ```python= arr4 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) print(arr4[0, 1, 2] + arr4[1, 0, 2]) #和list一樣,array也有負索引,因此可以用[-1]得到所求值 arr5 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]) print(arr5[1:7:2])#[起始:結束+1:遞增] #和list一樣,array也可以切割取值 arr6 = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]) print(arr6[1, 1:4]) print(arr6[1][1:4])#這兩行的效果一樣 print(arr6[0:2, 2])#下面的圖 ``` ![](https://i.imgur.com/HZrdyW4.png =530x) :goat:**NumPy中的數據類型** ```i```- 整數 ```b```- 布林值 ```u```- 無符號整數 ```f```- 浮點數 ```c```- 複數 ```m```- 時間 ```M```- 日期 ```O```- 物件 ```S```- 字串 ```U```- Unicode字符串 ```V```- void 可以使用```print(array.dtype)```來獲取資料型態。 - [ ] 程式碼 6.2.1d ```python= #直接將型態定義好 arr7 = np.array([1, 2, 3, 4], dtype='S4')#4-bytes,表示32位元容量 print(arr7) print(arr7.dtype) ``` - [ ] 程式碼 6.2.1e ```python= arr8 = np.array([1, 2, 3, 4, 5]) arr8_copy = arr8.copy() arr8[0] = 42 #想修改資料,但怕失去原始資料,就弄一份副本吧 print(arr8) print(arr8_copy) ``` #### 6.2.2 一點點的Matplotlib 大多數Matplotlib**實用**程序位於```pyplot```子模塊下,通常以```plt```別名導入。 Matplotlib也常常以```mpl```的姿態被導入。 ##### 劃一條線 在圖表中從位置(0,0)到位置(6,250)畫一條線: - [ ] 程式碼 6.2.2a ```python= import matplotlib.pyplot as plt import numpy as np#mpl常常搭配np xpoints = np.array([0, 6]) ypoints = np.array([0, 250]) plt.plot(xpoints, ypoints)#plot()繪圖,show()展示 plt.show() ``` ![](https://i.imgur.com/FPudiiz.png =350x) ##### 劃幾個點 在圖中畫兩個點,一個在位置(1, 3),一個在位置(8, 10): - [ ] 程式碼 6.2.2b ```python= x2points = np.array([1, 8]) y2points = np.array([3, 10]) plt.plot(x2points, y2points, 'o') plt.show() ``` ![](https://i.imgur.com/bMBRAtz.png =350x) ##### 畫軌跡圖 畫軌跡圖,從位置(1, 3)到(2, 8),然後到(6, 1),最後到位置(8, 10): - [ ] 程式碼 6.2.2c ```python= xpoints = np.array([1, 2, 6, 8]) ypoints = np.array([3, 8, 1, 10]) plt.plot(xpoints, ypoints, color='#000000') plt.plot(xpoints, ypoints, 'o', color='#000000') plt.show() ``` ![](https://i.imgur.com/mr2MTks.png =350x) 在學習matplotlib時,可以知道一個魔法函數(據說前綴%的都是魔法函數) ``` %matplotlib inline ``` 這邊有五段程式碼給你們回去玩~ ##### 6.2.2d - [ ] 程式碼 6.2.2d ```python= import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D %matplotlib inline def x(R,a,phi_1,phi_2): return((R+a*np.sin(phi_1))*np.cos(phi_2)) def y(R,a,phi_1,phi_2): return((R+a*np.sin(phi_1))*np.sin(phi_2)) def z(a,phi_1): return(a*np.cos(phi_1)) fig = plt.figure() ax = fig.add_subplot(111,projection = '3d') phi_1 = np.linspace(-2*np.pi, 2*np.pi, 50) phi_2 = np.linspace(-2*np.pi, 2*np.pi, 50) Phi_1, Phi_2 = np.meshgrid(phi_1, phi_2) X = x(2,1,Phi_1,Phi_2) Y = y(2,1,Phi_1,Phi_2) Z = z(1,Phi_1) ax.plot_surface(X, Y, Z, cmap=plt.cm.YlGnBu_r) plt.show() ``` ![](https://i.imgur.com/xxxPUS3.png =300x) ##### 6.2.2e - [ ] 程式碼 6.2.2e ```python= import matplotlib.pyplot as plt import numpy as np def f(x,y): return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)+5 xx,yy = np.meshgrid(np.linspace(-3,3,50),np.linspace(-3,3,50)) zz = f(xx,yy) plt.imshow(zz,origin='lower',extent=[xx.min(), xx.max(), yy.min(), yy.max()]) ``` ![](https://i.imgur.com/Hm6huC4.png =300x) ##### 6.2.2f - [ ] 程式碼 6.2.2f ```python= data = np.array([[ 0.45833279, 0.35737994, 0.54257486, 0.66908835], [ 0.19544843, 0.48287855, 0.97316904, 0.25445816], [ 0.44500619, 0.88060579, 0.74509425, 0.65703952], [ 0.80474809, 0.48011234, 0.05086501, 0.47188907]]) fig, ax = plt.subplots() heatmap = ax.pcolor(data, cmap=plt.cm.Greys) # put the major ticks at the middle of each cell ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False) ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False) # want a more natural, table-like display ax.invert_yaxis() ax.xaxis.tick_top() ax.set_xticklabels(['a','b','c','d'], minor=False) ax.set_yticklabels(['A','B','C','D'], minor=False) cbar = plt.colorbar(heatmap) ``` ![](https://i.imgur.com/RDLw1Nj.png =350x) ##### 6.2.2g - [ ] 程式碼 6.2.2g ```python= import matplotlib.pyplot as plt from mpl_toolkits.axes_grid.axislines import SubplotZero width = 1 # 兩條柱之間的距離 num = 5 #柱的個數 ind = np.arange(num) fig = plt.figure(figsize=(15, 4)) ax = SubplotZero(fig, 1, 3, 1) ax1 = fig.add_subplot(ax) means = [0.6481,0.6215,0.58,0.56,0.442] stds = [0.0129,0.0119,0.01,0.009,0.003] plt.bar(0.2+ind, means, 0.6*width,color=['k','r','c','y','r'], linewidth = 0.1, yerr=stds,error_kw=dict(elinewidth=1.5,ecolor='green')) plt.axis([0,5,0,1]) plt.ylabel(u'wPrecision') plt.grid() plt.xticks([]) ax = SubplotZero(fig, 1, 3, 2) ax2 = fig.add_subplot(ax) means = [0.341,0.39,0.42,0.48,0.582] stds = [0.0109,0.0149,0.02,0.011,0.009] plt.bar(0.2+ind, means, 0.6*width, color=['k','r','c','y','r'], linewidth = 0.1, yerr=stds,error_kw=dict(elinewidth=1.5,ecolor='green')) plt.axis([0,5,0,1]) plt.ylabel(u'wRecall') plt.grid() plt.xticks([]) ax = SubplotZero(fig, 1, 3, 3) ax3 = fig.add_subplot(ax) means = [0.68,0.6415,0.6,0.58,0.548] stds = [0.02,0.0119,0.0099,0.009,0.007] label = plt.bar(0.2+ind, means, 0.6*width, color=['k','r','c','y','r'],linewidth = 0.1, yerr=stds,error_kw=dict(elinewidth=1.5,ecolor='green')) plt.axis([0,5,0,1]) plt.ylabel(u'wF1') plt.grid() plt.xticks([]) fig.legend((label[0], label[1],label[2], label[3],label[4]), ('SVD-Single', 'SVD-Multiple','JNE','SNE','R2P'), 'upper center' ,ncol=5) ``` ![](https://i.imgur.com/nvvN0bi.png =900x) ##### 6.2.2h - [ ] 程式碼 6.2.2h ```python= fig = plt.figure() rect=[0.1,0.1,0.8,0.8] axprops = dict(xticks=[], yticks=[]) ax0=fig.add_axes(rect, label='ax0',**axprops) imgP = plt.imread("怕爆.jpg")##去電腦找圖片 ax0.imshow(imgP) ax1=fig.add_axes(rect, label='ax1',frameon=False) x = linspace(0,10,100) y = sin(x) ax1.plot(x,y) ax1.set_xlim([-2,12]) ax1.set_ylim([-5,12]) ax2=fig.add_axes(rect, label='ax2',frameon=False,**axprops) shodow_x = np.array([4.2, 4.2, 5.7, 5.8]) shodow_y = np.array([5.6, 7.2, 7.2, 5.5]) ax2.set_xlim([-2,12]) ax2.set_ylim([-5,12]) ax2.fill(shodow_x, shodow_y, linewidth=0, alpha=0.4, color='r') ax2.annotate('plot shadow area',xy=(5.7,7.2),xytext=(4.7,3.3),textcoords = 'offset points',arrowprops=dict(arrowstyle="->",connectionstyle="arc3"),fontsize=20) plt.show() ``` ![](https://i.imgur.com/Adlk0XA.png =400x) :::success :leaves:<font color=#227233><u>**Funny time**</u></font> **1.** 由於實際上print的語法這麼一長串, ```print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False))``` 我們可以嘗試更改它的```sep```、```end```...,像是 ```python print(1, 2, 3, 4, sep='✨', end='🤗') ``` **2.** 看看哪位勇者會想要打開這個潘朵拉盒子😏: ``` 你只需要在純文字檔(.txt)上打上「%0|%0」這五個字符 接著將存文字檔另存為.bat檔 之後,執行這個bat檔 你的電腦的效能將會完全被消耗殆盡,直到當機、或者是你強制重開機為止~ ``` 想了解更多關於這種打開檔案就自動執行的內容,可以🔎"**批次檔(Batch file)**" ::: ## Homework 6 [ZeroJudge](https://zerojudge.tw) * 本周題目: <font color = gray>a134: 00948 - Fibonaccimal Base</font> <font color = gray>a249: 00679 - Dropping Balls</font> <font color = gray>a261: 10934 - Dropping water balloons</font> <font color = gray>b421: 01077 - The Sky is the Limit 強化</font> <font color = gray>c061: 00530 - Binomial Showdown</font>