--- title: python讀書會(七) tags: python讀書會 notes: 爬蟲、神經網路、DL、%d、字串的速度文檔、比較速度實驗、unicode、輸入字元、array、作圖、讀寫檔案... --- {%hackmd @themes/orangeheart %} ## 7.0 期中後の小測驗 [kahoot!](https://kahoot.it/) (請隨時準備好講義翻找XDDD) ## 7.1 回顧... 1. 介紹set和dictionary的特性 2. numpy中的陣列 3. matplotlib作圖 ## 7.2 Numpy.Array #### 7.2.1 Array形狀 以前高中學習矩陣,矩陣有不同形狀,有二維方陣、矩形的二維陣列等等,現在我們不再是小孩了,我們學一點大人該學的...就是三維以上的陣列形狀!! 以下程式碼是檢驗矩陣形狀: - [ ] 程式碼 7.2.1a ```python= import numpy as np #創建一個三維矩陣 arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]) #檢查維度(ndim) print(arr3d.ndim) print(arr3d) #陣列形狀 print(arr3d.shape) ``` :cat:堆起陣列 - [ ] 程式碼 7.2.1b ```python= #重新塑形,數字是可以被每一維度的長度整除的 arr1d = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]) #讓一個有24個單元的一維陣列變成4x6的二維陣列 arr2d = arr1d.reshape(4, 6) print(arr2d) #或是4x2x3的三維陣列 arr3d = arr1d.reshape(4, 2, 3) print(arr3d) ################################ˇ arr1d_2 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]) arr3d_2 = arr1d_2.reshape(3, 2, -1) print(arr3d_2) ``` :cat:輾平陣列 - [ ] 程式碼 7.2.1c ```python= arr3d_3 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24]]]) arr1d_3 = arr3d_3.reshape(-1) print(arr1d_3) ``` 有很多函數可以改變numpy中陣列的形狀```flatten```,```ravel```也可以重新排列元素```rot90```、```flip```、```fliplr```等```flipud```。這些都屬於numpy的中級到高級部分(自行探索)。 #### 7.2.2 Array迭代 從陣列中提取數值,可以使用最直觀的迭代方式,也可以使用函數```nditer(array)```,更簡易地取出數值。 使用for loop: - [ ] 程式碼 7.2.2a ```python= arr1 = np.array([[1, 2, 3], [4, 5, 6]]) for i in arr1: print(i) ##################################### arr2 = np.array([[1, 2, 3], [4, 5, 6]]) for j in arr2: for k in j: print(k) ``` 使用```nditer(array)```: - [ ] 程式碼 7.2.2b ```python= arr3 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) for l in np.nditer(arr3): print(l) ################################################ arr4 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) for m in np.nditer(arr4[:, ::2]):#以跳躍的方式取出數值 print(m) ``` #### 7.2.3 Array連接與拆分 將矩陣裡面座標上的元素一一枚舉出來,枚舉的方向和順序都和數學上矩陣是相同的,不過程式碼都會從0開始: - [ ] 程式碼 7.2.3a ```python= #一維陣列 arr1D = np.array([1, 2, 3]) for a1, a2 in np.ndenumerate(arr1D): print(a1, a2) #################################### #二維陣列 arr2D = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) for a1, a2 in np.ndenumerate(arr2D): print(a1, a2) ``` ```concatenate```、```hstack```就像連接酶一樣將兩段單維陣列平行連接起來! 那如果是將兩個二維陣列或三維陣列連接起來呢? - [ ] 程式碼 7.2.3b ```python= arr1c = np.array([1, 2, 3]) arr2c = np.array([4, 5, 6]) arrc = np.concatenate((arr1c, arr2c)) print(arrc) ``` - [ ] 程式碼 7.2.3c ```python= arr1s = np.array([[1, 2, 3],[7, 8, 9]]) arr2s = np.array([[4, 5, 6],[10, 11, 12]]) arrs = np.stack((arr1s, arr2s), axis=2)#將連接軸改成1或0會發生神奇的事 print(arrs) ``` 既然陣列可以連接,那一定也可以拆開的對吧!```array_split```跟```split```不同之處在於,幾乎不會error,會自動調整元素的分配,並且返回一個list型態的資料。 - [ ] 程式碼 7.2.3d ```python= arr_complex = np.array([[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],[[21, 22, 23, 24], [25, 26, 27, 28], [29, 20, 31, 32]],[[41, 42, 43, 44], [45, 46, 47, 48], [49, 40, 51, 52]]]) newarr = np.array_split(arr_complex, 7, axis=2)#沿著第三軸分成7份,其實你要分成多少份都沒關係XDD print(newarr) ``` ## 7.3 Matplotlib :hand:[上次的Matplotlib](https://hackmd.io/@Poorbees-Squid/rybynDrmo#622-%E4%B8%80%E9%BB%9E%E9%BB%9E%E7%9A%84Matplotlib) 上次在matplotlib嘗試畫了只有數據點的點圖、只有線的線圖、以及有點有線的折線圖。 今天改變一些繪圖的參數改變其外型。 #### 7.3.1 線段樣式 - [ ] 程式碼 7.3.1 ```python= import matplotlib.pyplot as plt import numpy as np ypoints = np.array([3, 8, 1, 10]) plt.plot(ypoints, linestyle = 'dotted')#將xpoints省略也沒關係 plt.show() ``` 在上面這段程式碼當中第5行後面的```linestyle```寫成```ls```也可以,甚至連```'dotted'```都能縮寫成```':'``` 以下是線段樣式的寫法: ![](https://i.imgur.com/IRLJDa1.png =200x) #### 7.3.2 線段色彩 為了分辨代表不同數據的線條,我們可以像以下這樣更改線條顏色,改變顏色的方法有許多種(可以將```color```縮寫為```c```): - [ ] 程式碼 7.3.2a ```python= ypoints = np.array([3, 8, 1, 10]) plt.plot(ypoints, color = 'r')#red plt.show() ``` 除了關鍵字改變顏色以外,我們尚有**十六進制色碼(Colors HEX)**、**html色彩名稱(HTML Color Names)** 等方法改變線條顏色。 - [ ] 程式碼 7.3.2b ```htmlmixed 十六進制色碼 紅色: #ff0000 綠色: #00ff00 藍色: #0000ff #html色彩名稱 ``` - [ ] 程式碼 7.3.2 ```python= # evenly sampled time at 200ms intervals t = np.arange(0., 5., 0.2) # red dashes, blue squares and green triangles plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^') plt.show() ``` - [ ] 程式碼 7.3.2 ```python= ``` - [ ] 程式碼 7.3.2 ```python= ``` ## 7.4 爬蟲程式 :bug:**什麼是網路爬蟲?** 是一個透過程式**自動抓取**網站資料的過程,資料如果透過人工來收集,效率低會花費掉非常多的時間:cry:。 因此資料的收集與整理這份工作,可以透過網路爬蟲來協助,我們只要先制定好規則,就可以自動依照這規則收集和擷取資料並整理出我們所需的格式。 想從中央氣象局快速獲取大量數據來進行分析研究用途,就可以使用網路爬蟲這個利器。 要將資料從網站上爬下來,有3步驟: 1. **抵達目標網址:** 程式會回傳網頁原始碼(就是你在網站上按下F12看到的東西),它通常是由html寫成(改天可以快速教一下html,很快就能學會~) 2. **爬資料** 網路爬蟲主要是將html文件做解析並取出所需的資料,可以直接參考原始碼來寫程式。 3. **儲存資料** 將取出的資料儲存在CSV檔案、Excel表或是資料庫當中。 :::info CSV(comma-separated values): 就是記事本裡面的資料都用","隔開了。 ::: 但你以為所有資料都那麼好爬?有些地方設有反爬蟲機制(我還沒去研究喇QQ)會阻擋你的行為,~~如果你足夠執迷不悟~~,可以想想如何破解反爬蟲。 :::danger 網路爬蟲和網頁抓取並不違法,我們平日可以在Google上搜尋到資料,也是 Google 透過網路爬蟲來搜集來的。你的爬蟲如果不會造成網站負載,而且不要隨意去駭、去攻擊別人網頁,那就基本上沒問題。 ::: #### 7.4.1 爬蟲程式pytube 先玩一個簡單現成的爬蟲,後面有機會再慢慢教爬蟲~ pytube是用來下載youtube上影片的神奇程式,只需要短短的程式碼,就能輕易達到目的。 :TV:**mp4** - [ ] 程式碼 7.4.1a ```python= #先安裝好pytube程式 !pip install pytube#加上"!"表示在ipykernel上執行,如果不在ipykernel上即可去掉 import pytube from pytube import YouTube website = input("輸入影片網址:")#注意,經過奇怪機器轉換過的網址無效 target_path = "./Downloads" y = YouTube(website).streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first() y.download(output_path=target_path) ``` :notes:**mp3** - [ ] 程式碼 7.4.1b ```python= import pytube from pytube import YouTube import os url = input("請輸入網址:") target_path = "./Downloads" yt = YouTube(url) video = yt.streams.filter(only_audio=True).first() out_file = video.download(output_path=target_path) base, ext = os.path.splitext(out_file) new_file = base + '.mp3' os.rename(out_file, new_file) print("檔案位於 " + (new_file)) print("mp3已經成功下載~😏") ``` 可以嘗試將這些程式碼寫成一個軟件,放在電腦桌面上使用。 #### 7.4.2 爬蟲框架 一開始提到了,我們要爬就需要先抵達目標網址: 但是今天我會先停在這邊,如果之後有機會可以再繼續教爬蟲(因為我需要先教大家html和網頁的東西) - [ ] 程式碼 7.4 ```python= import requests#用來處理html的程式庫 res = requests.get(input('請輸入網址')) print(res.text)#得到網頁html框架的文檔 ``` ## Homework 7 * 本周題目:練習matplotlib繪圖,使自己有機會都用python作圖,而不是醜不拉基的excel和難用的SciDavis。 ![](https://i.imgur.com/CZHezcP.png =500x)