%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('http://stats.moe.gov.tw/files/detail/107/107_student.csv')
df.head()
大專校院校別學生數 | Unnamed: 1 | Unnamed: 2 | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 | Unnamed: 6 | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | ... | Unnamed: 15 | Unnamed: 16 | Unnamed: 17 | Unnamed: 18 | Unnamed: 19 | Unnamed: 20 | Unnamed: 21 | Unnamed: 22 | Unnamed: 23 | Unnamed: 24 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 107 學年度 SY2018-2019 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1 | 學校代碼 | 學校名稱 | 日間∕進修別 | 等級別 | 總計 | 男生計 | 女生計 | 一年級男生 | 一年級女生 | 二年級男生 | ... | 五年級男生 | 五年級女生 | 六年級男生 | 六年級女生 | 七年級男生 | 七年級女生 | 延修生男生 | 延修生女生 | 縣市名稱 | 體系別 |
2 | 0001 | 國立政治大學 | D 日 | D 博士 | 965 | 551 | 414 | 96 | 85 | 82 | ... | 71 | 52 | 58 | 46 | 74 | 40 | - | - | 30 臺北市 | 1 一般 |
3 | 0001 | 國立政治大學 | D 日 | M 碩士 | 3,998 | 1,854 | 2,144 | 624 | 742 | 632 | ... | - | - | - | - | - | - | - | - | 30 臺北市 | 1 一般 |
4 | 0001 | 國立政治大學 | D 日 | B 學士 | 9,630 | 3,983 | 5,647 | 899 | 1,287 | 890 | ... | - | - | - | - | - | - | 326 | 463 | 30 臺北市 | 1 一般 |
5 rows × 25 columns
欄位名稱被放到第 1 列, 真正要的資料從第二列開始!
colnames = df.loc[1].values
df = df[2:]
df.head()
大專校院校別學生數 | Unnamed: 1 | Unnamed: 2 | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 | Unnamed: 6 | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | ... | Unnamed: 15 | Unnamed: 16 | Unnamed: 17 | Unnamed: 18 | Unnamed: 19 | Unnamed: 20 | Unnamed: 21 | Unnamed: 22 | Unnamed: 23 | Unnamed: 24 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 0001 | 國立政治大學 | D 日 | D 博士 | 965 | 551 | 414 | 96 | 85 | 82 | ... | 71 | 52 | 58 | 46 | 74 | 40 | - | - | 30 臺北市 | 1 一般 |
3 | 0001 | 國立政治大學 | D 日 | M 碩士 | 3,998 | 1,854 | 2,144 | 624 | 742 | 632 | ... | - | - | - | - | - | - | - | - | 30 臺北市 | 1 一般 |
4 | 0001 | 國立政治大學 | D 日 | B 學士 | 9,630 | 3,983 | 5,647 | 899 | 1,287 | 890 | ... | - | - | - | - | - | - | 326 | 463 | 30 臺北市 | 1 一般 |
5 | 0001 | 國立政治大學 | N 職 | M 碩士 | 1,750 | 896 | 854 | 303 | 248 | 253 | ... | 53 | 47 | - | - | - | - | - | - | 30 臺北市 | 1 一般 |
6 | 0002 | 國立清華大學 | D 日 | D 博士 | 1,664 | 1,221 | 443 | 225 | 99 | 201 | ... | 158 | 50 | 112 | 43 | 168 | 58 | - | - | 18 新竹市 | 1 一般 |
5 rows × 25 columns
df.columns = colnames
df.head()
學校代碼 | 學校名稱 | 日間∕進修別 | 等級別 | 總計 | 男生計 | 女生計 | 一年級男生 | 一年級女生 | 二年級男生 | ... | 五年級男生 | 五年級女生 | 六年級男生 | 六年級女生 | 七年級男生 | 七年級女生 | 延修生男生 | 延修生女生 | 縣市名稱 | 體系別 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 0001 | 國立政治大學 | D 日 | D 博士 | 965 | 551 | 414 | 96 | 85 | 82 | ... | 71 | 52 | 58 | 46 | 74 | 40 | - | - | 30 臺北市 | 1 一般 |
3 | 0001 | 國立政治大學 | D 日 | M 碩士 | 3,998 | 1,854 | 2,144 | 624 | 742 | 632 | ... | - | - | - | - | - | - | - | - | 30 臺北市 | 1 一般 |
4 | 0001 | 國立政治大學 | D 日 | B 學士 | 9,630 | 3,983 | 5,647 | 899 | 1,287 | 890 | ... | - | - | - | - | - | - | 326 | 463 | 30 臺北市 | 1 一般 |
5 | 0001 | 國立政治大學 | N 職 | M 碩士 | 1,750 | 896 | 854 | 303 | 248 | 253 | ... | 53 | 47 | - | - | - | - | - | - | 30 臺北市 | 1 一般 |
6 | 0002 | 國立清華大學 | D 日 | D 博士 | 1,664 | 1,221 | 443 | 225 | 99 | 201 | ... | 158 | 50 | 112 | 43 | 168 | 58 | - | - | 18 新竹市 | 1 一般 |
5 rows × 25 columns
undergraduate = df[(df['日間∕進修別'] == 'D 日') & (df['等級別'] == 'B 學士')]
undergraduate.head()
學校代碼 | 學校名稱 | 日間∕進修別 | 等級別 | 總計 | 男生計 | 女生計 | 一年級男生 | 一年級女生 | 二年級男生 | ... | 五年級男生 | 五年級女生 | 六年級男生 | 六年級女生 | 七年級男生 | 七年級女生 | 延修生男生 | 延修生女生 | 縣市名稱 | 體系別 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
4 | 0001 | 國立政治大學 | D 日 | B 學士 | 9,630 | 3,983 | 5,647 | 899 | 1,287 | 890 | ... | - | - | - | - | - | - | 326 | 463 | 30 臺北市 | 1 一般 |
8 | 0002 | 國立清華大學 | D 日 | B 學士 | 8,689 | 4,696 | 3,993 | 1,089 | 865 | 1,087 | ... | - | - | - | - | - | - | 286 | 166 | 18 新竹市 | 1 一般 |
13 | 0003 | 國立臺灣大學 | D 日 | B 學士 | 16,604 | 9,447 | 7,157 | 2,126 | 1,525 | 2,110 | ... | 184 | 98 | 126 | 61 | 102 | 35 | 671 | 537 | 30 臺北市 | 1 一般 |
17 | 0004 | 國立臺灣師範大學 | D 日 | B 學士 | 8,079 | 3,583 | 4,496 | 846 | 1,066 | 850 | ... | - | - | - | - | - | - | 240 | 271 | 30 臺北市 | 3 師範 |
21 | 0005 | 國立成功大學 | D 日 | B 學士 | 11,390 | 7,123 | 4,267 | 1,672 | 1,010 | 1,651 | ... | 82 | 68 | 49 | 27 | 53 | 21 | 355 | 149 | 21 臺南市 | 1 一般 |
5 rows × 25 columns
注意接下來我們用了 copy
, 你可能感覺好像不需要用, 事實上沒有用也可以執行, 只是 pandas
會警告你...
這牽涉大概每個用 pandas
的人, 都會碰到的 SettingWithCopyWarning!
請參考這個影片, 理解要怎麼解決。事實上這是一個非常棒的 pandas
系列教學!
df2 = undergraduate.loc[:, '學校名稱':'女生計'].copy()
df2.head()
學校名稱 | 日間∕進修別 | 等級別 | 總計 | 男生計 | 女生計 | |
---|---|---|---|---|---|---|
4 | 國立政治大學 | D 日 | B 學士 | 9,630 | 3,983 | 5,647 |
8 | 國立清華大學 | D 日 | B 學士 | 8,689 | 4,696 | 3,993 |
13 | 國立臺灣大學 | D 日 | B 學士 | 16,604 | 9,447 | 7,157 |
17 | 國立臺灣師範大學 | D 日 | B 學士 | 8,079 | 3,583 | 4,496 |
21 | 國立成功大學 | D 日 | B 學士 | 11,390 | 7,123 | 4,267 |
我們來修正一下有逗點的數字...
import locale
# atof
locale.setlocale(locale.LC_NUMERIC, '')
'zh_TW.UTF-8'
df2['男生計'] = df2['男生計'].apply(locale.atof)
df2['女生計'] = df2['女生計'].apply(locale.atof)
df2['女男比例'] = df2.女生計 / df2.男生計
df2.head()
學校名稱 | 日間∕進修別 | 等級別 | 總計 | 男生計 | 女生計 | 女男比例 | |
---|---|---|---|---|---|---|---|
4 | 國立政治大學 | D 日 | B 學士 | 9,630 | 3983.0 | 5647.0 | 1.417776 |
8 | 國立清華大學 | D 日 | B 學士 | 8,689 | 4696.0 | 3993.0 | 0.850298 |
13 | 國立臺灣大學 | D 日 | B 學士 | 16,604 | 9447.0 | 7157.0 | 0.757595 |
17 | 國立臺灣師範大學 | D 日 | B 學士 | 8,079 | 3583.0 | 4496.0 | 1.254814 |
21 | 國立成功大學 | D 日 | B 學士 | 11,390 | 7123.0 | 4267.0 | 0.599045 |
找出女男比例最高前 20 所大學, 並且畫出圖來!
df3 = df2.sort_values(by = ['女男比例'], ascending=False)
df3[:20].plot.bar(x='學校名稱', y=['女男比例'])
<matplotlib.axes._subplots.AxesSubplot at 0x1249f29b0>
df = pd.read_html('https://browser.geekbench.com/mac-benchmarks')
len(df)
2
mac = df[0]
mac.head()
Mac | Score | Unnamed: 2 | |
---|---|---|---|
0 | iMac (27-inch Retina Mid 2017) Intel Core i7-7... | 5684 | NaN |
1 | Mac mini (Late 2018) Intel Core i7-8700B @ 3.2... | 5659 | NaN |
2 | MacBook Pro (15-inch Mid 2018) Intel Core i9-8... | 5347 | NaN |
3 | iMac Pro (Late 2017) Intel Xeon W-2150B @ 3.0 ... | 5320 | NaN |
4 | iMac (27-inch Retina Late 2015) Intel Core i7-... | 5282 | NaN |
mac[mac.Mac.str.contains('Mid 2018')]
Mac | Score | Unnamed: 2 | |
---|---|---|---|
2 | MacBook Pro (15-inch Mid 2018) Intel Core i9-8... | 5347 | NaN |
10 | MacBook Pro (13-inch Mid 2018) Intel Core i7-8... | 5138 | NaN |
13 | MacBook Pro (15-inch Mid 2018) Intel Core i7-8... | 5054 | NaN |
14 | MacBook Pro (15-inch Mid 2018) Intel Core i7-8... | 4926 | NaN |
22 | MacBook Pro (13-inch Mid 2018) Intel Core i5-8... | 4523 | NaN |
mac[mac.Score > 5347]
Mac | Score | Unnamed: 2 | |
---|---|---|---|
0 | iMac (27-inch Retina Mid 2017) Intel Core i7-7... | 5684 | NaN |
1 | Mac mini (Late 2018) Intel Core i7-8700B @ 3.2... | 5659 | NaN |
df = pd.read_html('http://www.9800.com.tw/statistics.asp')
len(df)
7
df_lot = df[3]
colnames = df_lot.loc[1].values
df_lot = df_lot.loc[2:]
df_lot.columns = colnames
df_lot.head()
期次 | 開獎日期 | 球號 | 特號 | 單雙 | 和值 | 均值 | 同尾 | 連號 | 首尾差 | 尾數和 | 首數和 | nan | nan | nan | nan | nan | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 108011 | 2019-02-02 | 02 | 07 | 22 | 35 | 46 | 49 | 41 | 3:3 | 161 | 26 | 2尾(2) | NaN | 47.0 | 31.0 | 13.0 |
3 | 108012 | 2019-02-03 | 12 | 24 | 28 | 36 | 37 | 40 | 6 | 1:5 | 177 | 29 | NaN | 3637 | 28.0 | 27.0 | 15.0 |
4 | 108013 | 2019-02-04 | 06 | 08 | 24 | 32 | 34 | 36 | 49 | 0:6 | 140 | 23 | 4尾(2), 6尾(2) | NaN | 30.0 | 30.0 | 11.0 |
5 | 108014 | 2019-02-05 | 13 | 18 | 30 | 34 | 45 | 49 | 33 | 3:3 | 189 | 31 | NaN | NaN | 36.0 | 29.0 | 16.0 |
6 | 108015 | 2019-02-06 | 17 | 23 | 28 | 29 | 32 | 39 | 12 | 4:2 | 168 | 28 | 9尾(2) | 2829 | 22.0 | 38.0 | 13.0 |
首先我們來讀入一個 CSV 檔, 這裡有個「假的」學測成績, 叫 grades.csv
我們來練習一下。
我們也有把檔案放在網路上, 所以可以用
pd.read_csv('https://bitly.com/gradescsv')
讀入。
df = pd.read_csv('dataset/grades.csv')
用 df
是標準的叫法 (雖然這名稱我們隨便取也可以), 意思是 Data Frame, 這是 pandas
兩大資料結構之一。我們可以把 Data Frame 想成一張表格 (雖然其實可以是很多張表格)。
我們來看看我們 df
的前五筆資料。
df.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | |
---|---|---|---|---|---|---|
0 | 劉俊安 | 9 | 10 | 15 | 10 | 13 |
1 | 胡玉華 | 10 | 10 | 10 | 8 | 9 |
2 | 黃淑婷 | 13 | 15 | 8 | 11 | 14 |
3 | 陳上紫 | 10 | 10 | 8 | 9 | 14 |
4 | 崔靜成 | 13 | 12 | 14 | 12 | 13 |
如果你曾經手動讀入 CSV 檔, 就知道這省了多少事 (雖然我個人還挺喜歡純手動帶進 CSV)。
不只 CSV 檔, 很多資料檔案, 像 Excel 檔都很容易在 pandas
完成。使用法是這樣:
df2 = pd.read_excel('filename.xls', 'sheetname')
其中 sheetname 那裡要放工作表的名稱, 如果是中文的最好改成英文。
剛剛說 series 大概就是一個 list, 一個 array。其實更精準的說, 其實是一個有 "index" 的 array。
DataFrame 的每一行或每一列其實也都是一個 series。我們來看個例子, 例如所有同學的國文成績, 就是一個 series。
df['國文']
0 9 1 10 2 13 3 10 4 13 5 13 6 11 7 8 8 9 9 10 10 14 11 13 12 11 13 15 14 8 15 11 16 14 17 12 18 9 19 14 20 13 21 9 22 12 23 10 24 10 25 13 26 13 27 8 28 15 29 14 .. 70 9 71 9 72 10 73 13 74 14 75 13 76 9 77 13 78 12 79 9 80 13 81 11 82 11 83 10 84 10 85 10 86 11 87 10 88 11 89 13 90 8 91 14 92 8 93 11 94 10 95 9 96 8 97 14 98 15 99 9 Name: 國文, Length: 100, dtype: int64
在 Python 3 中, 我們終於可以和英文同步, 用這種很炫的方式叫出所有國文成績。
df.國文
0 9 1 10 2 13 3 10 4 13 5 13 6 11 7 8 8 9 9 10 10 14 11 13 12 11 13 15 14 8 15 11 16 14 17 12 18 9 19 14 20 13 21 9 22 12 23 10 24 10 25 13 26 13 27 8 28 15 29 14 .. 70 9 71 9 72 10 73 13 74 14 75 13 76 9 77 13 78 12 79 9 80 13 81 11 82 11 83 10 84 10 85 10 86 11 87 10 88 11 89 13 90 8 91 14 92 8 93 11 94 10 95 9 96 8 97 14 98 15 99 9 Name: 國文, Length: 100, dtype: int64
要畫個圖很容易。
df.國文.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1151687f0>
當然, 在這個例子中, 其實畫 histogram 圖更有意義一點。
df.國文.hist(bins=15)
<matplotlib.axes._subplots.AxesSubplot at 0x1171e4e10>
算平均。
df.國文.mean()
11.39
算標準差。
df.國文.std()
2.1968526614594834
不如就該算的都幫我們算算...
df.describe()
國文 | 英文 | 數學 | 自然 | 社會 | |
---|---|---|---|---|---|
count | 100.000000 | 100.000000 | 100.000000 | 100.00000 | 100.00000 |
mean | 11.390000 | 11.380000 | 11.570000 | 11.03000 | 11.83000 |
std | 2.196853 | 2.273164 | 2.310516 | 2.21772 | 2.48655 |
min | 8.000000 | 8.000000 | 8.000000 | 8.00000 | 8.00000 |
25% | 9.000000 | 9.000000 | 10.000000 | 9.00000 | 9.00000 |
50% | 11.000000 | 11.000000 | 11.000000 | 11.00000 | 12.00000 |
75% | 13.000000 | 13.000000 | 14.000000 | 13.00000 | 14.00000 |
max | 15.000000 | 15.000000 | 15.000000 | 15.00000 | 15.00000 |
有時我們很愛看的相關係數矩陣。
df.corr()
國文 | 英文 | 數學 | 自然 | 社會 | |
---|---|---|---|---|---|
國文 | 1.000000 | 0.160158 | -0.310899 | -0.110236 | -0.028421 |
英文 | 0.160158 | 1.000000 | 0.025656 | 0.113929 | -0.063512 |
數學 | -0.310899 | 0.025656 | 1.000000 | 0.014371 | 0.041651 |
自然 | -0.110236 | 0.113929 | 0.014371 | 1.000000 | -0.156594 |
社會 | -0.028421 | -0.063512 | 0.041651 | -0.156594 | 1.000000 |
只算兩科間的相關係數當然也可以。
df.國文.corr(df.數學)
-0.3108989822179331
df['總級分'] = df.sum(axis=1)
df.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | |
---|---|---|---|---|---|---|---|
0 | 劉俊安 | 9 | 10 | 15 | 10 | 13 | 57 |
1 | 胡玉華 | 10 | 10 | 10 | 8 | 9 | 47 |
2 | 黃淑婷 | 13 | 15 | 8 | 11 | 14 | 61 |
3 | 陳上紫 | 10 | 10 | 8 | 9 | 14 | 51 |
4 | 崔靜成 | 13 | 12 | 14 | 12 | 13 | 64 |
有計算的當然也可以的。
df['加權'] = df.數學 * 2 + df.英文 * 1.5 + df.社會
df.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
0 | 劉俊安 | 9 | 10 | 15 | 10 | 13 | 57 | 58.0 |
1 | 胡玉華 | 10 | 10 | 10 | 8 | 9 | 47 | 44.0 |
2 | 黃淑婷 | 13 | 15 | 8 | 11 | 14 | 61 | 52.5 |
3 | 陳上紫 | 10 | 10 | 8 | 9 | 14 | 51 | 45.0 |
4 | 崔靜成 | 13 | 12 | 14 | 12 | 13 | 64 | 59.0 |
df.sort_values(by='總級分', ascending=False).head(10)
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
80 | 施雅鈴 | 13 | 15 | 12 | 13 | 13 | 66 | 59.5 |
12 | 李正偉 | 11 | 15 | 11 | 14 | 15 | 66 | 59.5 |
54 | 陳怡潔 | 15 | 15 | 9 | 15 | 11 | 65 | 51.5 |
25 | 蔡亦瑄 | 13 | 13 | 14 | 13 | 12 | 65 | 59.5 |
57 | 胡淳茜 | 12 | 15 | 14 | 13 | 11 | 65 | 61.5 |
37 | 曾怡君 | 11 | 12 | 15 | 13 | 14 | 65 | 62.0 |
48 | 陳怡婷 | 15 | 14 | 12 | 9 | 15 | 65 | 60.0 |
64 | 俞志峰 | 9 | 14 | 13 | 14 | 15 | 65 | 62.0 |
83 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 65 | 64.0 |
87 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 65 | 62.5 |
加權分最高, 同分才看總級分
df2 = df.sort_values(by = ['加權', '總級分'], ascending=False)
df2.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
83 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 65 | 64.0 |
36 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 64 | 63.5 |
70 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 59 | 63.5 |
68 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 64 | 63.0 |
87 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 65 | 62.5 |
df2.index = range(1, 101)
df2.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 65 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 64 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 59 | 63.5 |
4 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 64 | 63.0 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 65 | 62.5 |
df2.數學 == 15
1 True 2 True 3 True 4 False 5 False 6 True 7 False 8 True 9 False 10 True 11 False 12 True 13 False 14 True 15 False 16 False 17 False 18 False 19 False 20 True 21 False 22 True 23 False 24 True 25 False 26 False 27 False 28 False 29 False 30 False ... 71 False 72 False 73 False 74 False 75 False 76 False 77 False 78 False 79 False 80 False 81 False 82 False 83 False 84 False 85 False 86 False 87 False 88 False 89 False 90 False 91 False 92 False 93 False 94 False 95 False 96 False 97 False 98 False 99 False 100 False Name: 數學, Length: 100, dtype: bool
df2[df2.數學 == 15]
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 65 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 64 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 59 | 63.5 |
6 | 曾怡君 | 11 | 12 | 15 | 13 | 14 | 65 | 62.0 |
8 | 陳竹伯 | 10 | 12 | 15 | 10 | 14 | 61 | 62.0 |
10 | 胡勝傑 | 8 | 11 | 15 | 10 | 15 | 59 | 61.5 |
12 | 吳志遠 | 13 | 15 | 15 | 8 | 8 | 59 | 60.5 |
14 | 周育霖 | 9 | 12 | 15 | 13 | 12 | 61 | 60.0 |
20 | 劉俊安 | 9 | 10 | 15 | 10 | 13 | 57 | 58.0 |
22 | 林哲法 | 14 | 9 | 15 | 10 | 14 | 62 | 57.5 |
24 | 段冠廷 | 9 | 8 | 15 | 12 | 15 | 59 | 57.0 |
36 | 張雅彬 | 10 | 11 | 15 | 12 | 8 | 56 | 54.5 |
46 | 芮秋辛 | 11 | 10 | 15 | 10 | 8 | 54 | 53.0 |
找出數學和英文都滿級分的同學。要注意 and
要用 &
, or
要用 |
。每個條件一定要加弧號。
df2[(df2.數學 == 15) & (df2.英文 > 13)]
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 65 | 64.0 |
12 | 吳志遠 | 13 | 15 | 15 | 8 | 8 | 59 | 60.5 |
df2.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 65 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 64 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 59 | 63.5 |
4 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 64 | 63.0 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 65 | 62.5 |
df2.drop('總級分', axis=1).head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 加權 | |
---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 63.5 |
4 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 63.0 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 62.5 |
df2.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 總級分 | 加權 | |
---|---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 65 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 64 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 59 | 63.5 |
4 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 64 | 63.0 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 65 | 62.5 |
df2.drop('總級分', axis=1, inplace=True)
df2.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 加權 | |
---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 63.5 |
4 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 63.0 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 62.5 |
刪掉列就是指定要刪去的 index。
df2.head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 加權 | |
---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 63.5 |
4 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 63.0 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 62.5 |
df2.drop(5).head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 加權 | |
---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 63.5 |
4 | 劉麗芬 | 8 | 14 | 14 | 14 | 14 | 63.0 |
6 | 曾怡君 | 11 | 12 | 15 | 13 | 14 | 62.0 |
通常刪掉符合條件的比較合理 (注意是找到要刪掉的部份, 再找出相對的 index)。
df2.drop(df2[df2.姓名=='劉麗芬'].index).head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 加權 | |
---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 63.5 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 62.5 |
6 | 曾怡君 | 11 | 12 | 15 | 13 | 14 | 62.0 |
聰明的你是不是想到, 那直接篩出我們要留的就好了啊!
df2[df2.姓名 != '劉麗芬'].head()
姓名 | 國文 | 英文 | 數學 | 自然 | 社會 | 加權 | |
---|---|---|---|---|---|---|---|
1 | 李士賢 | 10 | 14 | 15 | 13 | 13 | 64.0 |
2 | 詹威德 | 12 | 13 | 15 | 10 | 14 | 63.5 |
3 | 葉儀依 | 9 | 13 | 15 | 8 | 14 | 63.5 |
5 | 趙偉希 | 10 | 13 | 14 | 13 | 15 | 62.5 |
6 | 曾怡君 | 11 | 12 | 15 | 13 | 14 | 62.0 |
有個從 Pandas
獨立出來的套件叫 pandas-datareader
, 幾經波折, 先是 Yahoo! 的財務資料不能用, 後來又是 Google 的資料不能用, 不過至少現在看來 Yahoo! 還可以使用。
安裝 pandas-datareader
就標準 conda
安裝:
conda install pandas-datareader
如果裝過, 但很久沒更新就用:
conda update pandas-datareader
要注意這些指令是要在終端機下的, 如果堅持不要離開 Jupyter Notebook 的安裝, 可以用:
!conda install pandas-datareader -y
你要記得下達 -y
這個動作, 不然你的電腦會永遠在那等你按 y
, 但你其實按不了...
import pandas_datareader as pdr
df = pdr.get_data_yahoo('AAPL')
df.to_csv('dataset/aapl.csv')
我們把這個檔案以 aapl.csv
存起來, 之後可以這樣讀入。
df = pd.read_csv('dataset/aapl.csv', index_col="Date")
df.head()
High | Low | Open | Close | Volume | Adj Close | |
---|---|---|---|---|---|---|
Date | ||||||
2009-12-31 | 30.478571 | 30.080000 | 30.447144 | 30.104286 | 88102700.0 | 20.073631 |
2010-01-04 | 30.642857 | 30.340000 | 30.490000 | 30.572857 | 123432400.0 | 20.386072 |
2010-01-05 | 30.798571 | 30.464285 | 30.657143 | 30.625713 | 150476200.0 | 20.421322 |
2010-01-06 | 30.747143 | 30.107143 | 30.625713 | 30.138571 | 138040000.0 | 20.096491 |
2010-01-07 | 30.285715 | 29.864286 | 30.250000 | 30.082857 | 119282800.0 | 20.059338 |
df = df[-240:]
df.Close.plot()
df.Close.rolling(20).mean().plot()
<matplotlib.axes._subplots.AxesSubplot at 0x117f51828>
df.Close.plot(legend=True)
df.Close.rolling(20).mean().plot(label="$MA_{20}$", legend=True)
df.Close.rolling(60).mean().plot(label="$MA_{60}$", legend=True)
<matplotlib.axes._subplots.AxesSubplot at 0x117f01710>
有時我們用手工打造一個簡單的 DataFrame, 可以更理解整個結構。其實很容易, 一個 DataFrame 基本上就包含兩個主要部份:
我們來個簡單的小例子。
mydata = np.random.randn(4,3)
mydata
array([[ 1.21822157, -0.25159939, -0.19534263], [ 0.10606576, -0.39832127, -1.42026132], [-1.95442479, -1.717565 , 0.92151077], [ 1.14457225, 0.71271714, -0.09496264]])
把行列的名字放進去, 就成一個 DataFrame。我們列的部份先讓 Python 自己產生。
df = pd.DataFrame(mydata, columns=list('ABC'))
df
A | B | C | |
---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 |
1 | 0.106066 | -0.398321 | -1.420261 |
2 | -1.954425 | -1.717565 | 0.921511 |
3 | 1.144572 | 0.712717 | -0.094963 |
我們再來生一個 DataFrame, 再「貼」起來。
df2 = pd.DataFrame(np.random.randn(3,3), columns=list('ABC'))
df2
A | B | C | |
---|---|---|---|
0 | -0.033421 | -0.281653 | 1.243136 |
1 | 1.776597 | 0.665904 | 1.747222 |
2 | 0.079714 | -2.033644 | -1.908974 |
df
A | B | C | |
---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 |
1 | 0.106066 | -0.398321 | -1.420261 |
2 | -1.954425 | -1.717565 | 0.921511 |
3 | 1.144572 | 0.712717 | -0.094963 |
df3 = pd.concat([df, df2], axis = 0)
df3
A | B | C | |
---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 |
1 | 0.106066 | -0.398321 | -1.420261 |
2 | -1.954425 | -1.717565 | 0.921511 |
3 | 1.144572 | 0.712717 | -0.094963 |
0 | -0.033421 | -0.281653 | 1.243136 |
1 | 1.776597 | 0.665904 | 1.747222 |
2 | 0.079714 | -2.033644 | -1.908974 |
df3.index = range(7)
df3
A | B | C | |
---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 |
1 | 0.106066 | -0.398321 | -1.420261 |
2 | -1.954425 | -1.717565 | 0.921511 |
3 | 1.144572 | 0.712717 | -0.094963 |
4 | -0.033421 | -0.281653 | 1.243136 |
5 | 1.776597 | 0.665904 | 1.747222 |
6 | 0.079714 | -2.033644 | -1.908974 |
前面我們弄得亂七八糟的 index 重設一下。
df
A | B | C | |
---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 |
1 | 0.106066 | -0.398321 | -1.420261 |
2 | -1.954425 | -1.717565 | 0.921511 |
3 | 1.144572 | 0.712717 | -0.094963 |
df2
A | B | C | |
---|---|---|---|
0 | -0.033421 | -0.281653 | 1.243136 |
1 | 1.776597 | 0.665904 | 1.747222 |
2 | 0.079714 | -2.033644 | -1.908974 |
等等, 這大小好像不太對也可以嗎? 答案是可以的!
dfx = pd.concat([df, df2], axis=1)
dfx
A | B | C | A | B | C | |
---|---|---|---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 | -0.033421 | -0.281653 | 1.243136 |
1 | 0.106066 | -0.398321 | -1.420261 | 1.776597 | 0.665904 | 1.747222 |
2 | -1.954425 | -1.717565 | 0.921511 | 0.079714 | -2.033644 | -1.908974 |
3 | 1.144572 | 0.712717 | -0.094963 | NaN | NaN | NaN |
dfx.dropna()
A | B | C | A | B | C | |
---|---|---|---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 | -0.033421 | -0.281653 | 1.243136 |
1 | 0.106066 | -0.398321 | -1.420261 | 1.776597 | 0.665904 | 1.747222 |
2 | -1.954425 | -1.717565 | 0.921511 | 0.079714 | -2.033644 | -1.908974 |
dfx.fillna(0)
A | B | C | A | B | C | |
---|---|---|---|---|---|---|
0 | 1.218222 | -0.251599 | -0.195343 | -0.033421 | -0.281653 | 1.243136 |
1 | 0.106066 | -0.398321 | -1.420261 | 1.776597 | 0.665904 | 1.747222 |
2 | -1.954425 | -1.717565 | 0.921511 | 0.079714 | -2.033644 | -1.908974 |
3 | 1.144572 | 0.712717 | -0.094963 | 0.000000 | 0.000000 | 0.000000 |