Py / Python網頁資料擷取與分析班-筆記 10/11

主要內容

_303題果菜批發市場拍賣行情
_305題登革熱病例統計用groupby群組與統計
_401題資料折線圖繪製說明
_403題長條圖與圓餅圖與複合圖
_405題樣本:直方圖與散佈圖


1.303題果菜批發市場拍賣行情

直接在程式裡建構資料

選取、修改資料的方式比較簡單,等於是依據變數資料型態來使用對應的方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 303果菜批發市場拍賣行情

# 載入 pandas 模組縮寫為 pd
import pandas as pd
# 建構資料
datas = [[9, 203674, 13.2, 18894],
         [11.7, 180785, 12.3, 54894],
         [10.1, 127802, 14.7, 18563],
         [11.8, 28604, 14.9, 21963],
         [13.2, 600, 13.1, 900],
         [6.9, 38071, 9.6, 3555],
         [12.1, 35660, 10.6, 9005],
         [12, 15000, 13, 12000],
         [11.7, 48770, 9.1, 14370],
         [9.84, 6100, 11.89, 8980]]
indexs = ["三重市", "台中市", "台北一", "台北二", "台東市", "板橋區", "高雄市", "嘉義市", "鳳山區", "豐原區"]
columns = ["西瓜價", "西瓜量", "香瓜價", "香瓜量"]
# 輸出如拍賣行情價量表
df = pd.DataFrame(datas, columns=columns,  index=indexs)

print('西瓜與香瓜之拍賣行情價量表')
print(df)
print()  # 使用print分隔

# 以西瓜價遞減排序後,輸出各市場的西瓜價
df1 = df.sort_values(by="西瓜價", ascending=False)
print('以西瓜價遞減排序')
print(df1['西瓜價'])
print()  # 使用print分隔

# 計算台北一市場西瓜/香瓜價量的行情並輸出
df.loc["台北一"]
print('台北一市場的行情')
print(df.loc["台北一"])
print()  # 使用print分隔

# 將「三重市」改為「三重區」
indexs[0] = "三重區"
#「香瓜價」改為「洋香瓜價」
columns[2] = "洋香瓜價"
#「香瓜量」改為「洋香瓜量」
columns[3] = "洋香瓜量"
# 重新輸出整個表格
df.index = indexs
df.columns = columns

print('全體市場行情')
print(df)

 

如果是讀取本機資料的話,要指定哪一個欄位為index

選取資料的方式跟從程式建構資料的方式一樣

最大的差別是修改資料

如果是修改column

df.rename(columns={“香瓜價”:“洋香瓜價”,“香瓜量”:“洋香瓜量”}, inplace=True)

如果是修改index

df.rename(index={“三重市”:“三重區”}, inplace=True)

如果要修改資料的話

可以使用iloc( )定位之後直接修改

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 303果菜批發市場拍賣行情

# 載入 pandas 模組縮寫為 pd
import pandas as pd

# 讀取本機檔案 並以"市場名稱"欄位為index
df = pd.read_csv("read303.csv", index_col="市場名稱",encoding="cp950")
print(df)

print('西瓜與香瓜之拍賣行情價量表')
print(df)
print()  # 使用print分隔
# 
# 以西瓜價遞減排序後,輸出各市場的西瓜價
df1 = df.sort_values(by="西瓜價", ascending=False)
print('以西瓜價遞減排序')
print(df1['西瓜價'])
print()  # 使用print分隔

# 計算台北一市場西瓜/香瓜價量的行情並輸出
df.loc["台北一"]
print('台北一市場的行情')
print(df.loc["台北一"])
print()  # 使用print分隔
# 
# 將「三重市」改為「三重區」
# 「香瓜價」改為「洋香瓜價」
# 「香瓜量」改為「洋香瓜量」

df.rename(index={"三重市":"三重區"}, inplace=True)
print(df.index)

df.rename(columns={"香瓜價":"洋香瓜價","香瓜量":"洋香瓜量"}, inplace=True)
print(df.columns)

print()  # 使用print分隔
print('全體市場行情')
print(df)

 

2.305題登革熱病例統計用groupby群組與統計

老師的範例是Python 3擷取與分析證照考試的標準答案

居住縣市病例人數,並按遞減順序顯示

df_county = df1.groupby(“居住縣市”)[“居住縣市”].count()

df_county.sort_values(ascending=False)

其實可以合併成

df1.groupby(“居住縣市”)[“居住縣市”].count().sort_values(ascending=False)

使用groupby()分群再取出”居住縣市”以count( )計數,最後再用sort_values( )排序

也等於df1.groupby(“居住縣市”).居住縣市.count().sort_values(ascending=False)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 305登革熱病例統計

# 載入 pandas 模組縮寫為 pd
import pandas as pd
# 讀取csv檔
#df1 = pd.read_csv('read305.csv', encoding="utf-8", sep=",", header=0)
df1 = pd.read_csv('read305.csv', encoding="utf-8")
# 居住縣市病例人數,並按遞減順序顯示
df_county = df1.groupby("居住縣市")["居住縣市"].count()
#print(df_county)
print(df_county.sort_values(ascending=False))
# 顯示感染病例人數最多的5個國家,並按遞減順序顯示
df_country = df1.groupby("感染國家")["感染國家"].count()
print(df_country.sort_values(ascending=False).head(5))
# 台北市各區病例人數
df_taipei = df1[df1.居住縣市 == "台北市"]
print(df_taipei.groupby("居住鄉鎮")["居住鄉鎮"].count())
# 台北市最近病例的日期
print("發病日: " + df_taipei.發病日.max())

 

我嘗試用其他的方法來達成相同的效果

居住縣市病例人數,並按遞減順序顯示

df1.groupby(“居住縣市”).size().sort_values(ascending=False)

使用size( )取得”居住縣市”各分群的大小(數量),再用sort_values( )排序

台北市各區病例人數

先將整體資料以”居住縣市”分群,取得分群中的”台北市”,再用”居住鄉鎮”進一步分群,然後用size( )取得各分群的大小(數量)

台北市最近病例的日期

也是先將整體資料以”居住縣市”分群,取得分群中的”台北市”,然後以max( )取得”發病日”的最大值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 305登革熱病例統計

# 載入 pandas 模組縮寫為 pd
import pandas as pd
# 讀取csv檔
#df1 = pd.read_csv('read305.csv', encoding="utf-8", sep=",", header=0)
df1 = pd.read_csv('read305.csv', encoding="utf-8")
# 居住縣市病例人數,並按遞減順序顯示
print("居住縣市病例人數,並按遞減順序顯示")
print()

print(df1.groupby("居住縣市").size())
print(df1.groupby("居住縣市").size().sort_values(ascending=False))

# # 顯示感染病例人數最多的5個國家,並按遞減順序顯示
print()
print("顯示感染病例人數最多的5個國家,並按遞減順序顯示")
print(df1.groupby("感染國家").size().sort_values(ascending=False).head(5))

df_county = df1.groupby("居住縣市")
# # 台北市各區病例人數
print()
print("台北市各區病例人數")
print(df_county.get_group("台北市").groupby("居住鄉鎮").size())

# # 台北市最近病例的日期
print()
print("台北市最近病例的日期")
print(df_county.get_group("台北市").發病日.max())
print(df_county.get_group("台北市")["發病日"].max())

 

3.401題資料折線圖繪製說明

plt.plot的參數基本設定(x, y),至少需要有X軸數值以及Y軸數值

比較需要注意的是設定字體的方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#401資料:折線圖
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt

# 設定字體的檔案位置,並放到fm.FontProperties裡
fontPath = r"C:\Windows\Fonts\msjh.ttc"
fontConfig = fm.FontProperties(fname=fontPath, size=18)

data1 = [1, 4, 9, 16, 25, 36, 49, 64]
data2 = [1, 2, 3, 6, 9, 15, 24, 39]
seq=range(1,len(data1)+1)
plt.plot(seq, data1, 'bo--', seq, data2, 'ro--', linewidth=2)
plt.axis([0, 8, 0, 70])
plt.title("折線圖", fontproperties=fontConfig)
plt.xlabel("x軸", fontproperties=fontConfig)
plt.ylabel("y軸", fontproperties=fontConfig)
plt.show()
# 輸出圖片檔案
# plt.savefig('chart.png')
#plt.close()

 

4.403題長條圖與圓餅圖與複合圖

利用plt.subplot(nrows, ncols, index )來設定複合圖的呈現方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#403月份統計:長條圖與圓餅圖
# 載入 matplotlib.pyplot 並縮寫為 plt
import matplotlib.pyplot as plt
# 四個月份
labels = ["Jun", "Jul", "Aug", "Sep"]
sizes = [20, 30, 40, 10]
# 圓餅圖顏色
colors = ["yellowgreen", "gold", "lightskyblue", "lightcoral"]

# 長條圖 位置
plt.subplot(1, 2, 1)
xticks = range(1, len(labels) + 1)
# 長條圖以labels為X軸,sizes為Y軸,各長條顏色為藍色(blue)
plt.xticks(xticks, labels)
plt.bar(xticks, sizes, color="blue")

# 圓餅圖 位置
plt.subplot(1, 2, 2)
# 圓餅圖以labels為圖標,sizes為各項所占百分比
# 圓餅圖colors為各項顏色,突顯「Aug」
# 圓餅圖顯示各項百分比到小數點第1位
explode = [0, 0, 0.1, 0]
plt.pie(sizes, explode=explode, labels=labels,
        colors=colors, autopct="%1.1f%%")
# 長寬比為1:1
# plt.axis("equal")
# plt.savefig("chart.png")
# plt.close()
plt.show()

 

5.405樣本:直方圖與散佈圖

使用numpy套件來產生數值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#405樣本:直方圖與散佈圖
# 在 import matplotlib.pyplot as plt 之前執行執行 mpl.use("Agg")
# 將不會顯示圖示 即使 plt.show()
# 如果要恢復
# 需要執行 # mpl.use("TKAgg")
# =============================================================================
# import matplotlib as mpl
# mpl.use("Agg")
# =============================================================================

# np.random.RandomState()的隨機值
# 如果為 None 每次都會產生不同的隨機值
# 如果是一個固定數值  每次都會產生相同的隨機值
set_seed = 123
import numpy as np
import matplotlib.pyplot as plt

#從常態分布(平均數1 標準差0.5)中隨機抽取1000個數值
samples_1 = np.random.RandomState(set_seed).normal(loc=1, scale=0.5, size=1000)

#從df自由度的標準Student t分布中隨機抽取1000個數值。
samples_2 = np.random.RandomState(set_seed).standard_t(df=10, size=1000)

#print(samples_1)
# print(samples_2)

#產生介於-3 3之間均勻等差數列 數據量為100個
bins = np.linspace(-3, 3, 100)
# print(bins)

# 第一個子圖 直方圖(histogram)
plt.subplot(2, 2, 1)
plt.hist(samples_1, bins=bins, alpha=0.5, label="samples 1")
plt.hist(samples_2, bins=bins, alpha=0.5, label="samples 2")
# 在左上角 upper left 放置圖例 legend
plt.legend(loc="upper left")

# 第二個子圖 散佈圖(scatter)
plt.subplot(1, 2, 2)
plt.scatter(samples_1, samples_2, alpha=0.2)

plt.show()
# plt.savefig("chart.png")
# plt.close()

 

參考資料:

由 Pandas 的 DataFrame 中取得資料
[Day10]Pandas Groupby使用!
numpy.random.RandomState
Python 繪製折線圖 Plot Line Charts
matplotlib.pyplot.subplot
Matplotlib 饼图
py数分笔记(3):np.random.seed()与np.random.RandomState()
【Python】np.linspace用法介紹
掌握了Matplotlib這兩個方法,輕鬆繪製出漂亮的直方圖!
Python matplotlib.pyplot.scatter()用法及代碼示例
matplotlib.use(‘agg’)的作用
解决 Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure