---
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'```都能縮寫成```':'```
以下是線段樣式的寫法:

#### 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。
