class 2-3 小專案練習
阿新 • • 發佈:2018-11-03
空氣質量分指數計算方法(框架)
1 def cal_liner(iaqi_lo,iaqi_hi,bp_lo,bp_hi,cp): 2 """範圍縮放""" 3 iaqi =(iaqi_hi - iaqi_lo)*(cp -bp_lo) /(bp_hi - bp_lo) + iaqi_lo 4 return iaqi 5 6 def cal_pm_iaqi(pm_val): 7 if 0 <= pm_val <36: 8 pm_iaqi = cal_liner(0,50,0,35,pm_val) 9 elifView Code36 <= pm_val <76: 10 pm_iaqi = cal_liner(0,100,35,75,pm_val) 11 elif 76 <= pm_val < 116: 12 pm_iaqi = cal_liner(0, 150, 75, 115, pm_val) 13 else: 14 pass 15 16 def cal_co_iaqi(co_val): 17 if 0 <= co_val <3: 18 co_iaqi = cal_liner(0,50,0,3,co_val)19 elif 3 <= co_val <5: 20 co_iaqi = cal_liner(0,100,2,4,co_val) 21 else: 22 pass 23 24 def cal_aqi(param_list): 25 pm_val = param_list[0] 26 co_val = param_list[1] 27 pm_iaqi = cal_pm_iaqi(pm_val) 28 co_iaqi = cal_pm_iaqi(co_val) 29 iaqi_list = [] 30 iaqi_list.append(pm_iaqi)31 iaqi_list.append(co_iaqi) 32 33 aqi = max(iaqi_list) 34 return aqi 35 36 def main(): 37 print('請輸入以下資訊,使用空格分割') 38 input_str = input('(1)PM2.5 (2)CO:') 39 str_list = input_str.split(' ') 40 pm_val = float(str_list[0]) 41 co_val = float(str_list[1]) 42 param_list = [] 43 param_list.append(pm_val) 44 param_list.append(co_val) 45 #呼叫AQI計算函式 46 aqi_val = cal_aqi(param_list) 47 print('空氣質量指數為:{}'.format(aqi_val)) 48 49 if __name__ == '__main__': 50 main()
- JSON(javaScript Object Notation)是一種輕量級資料交換格式
- 可以對複雜資料進行表達和儲存,易於閱讀和理解
- 規則
- 資料儲存在鍵值對中
- 鍵值對之間由逗號分隔
- 花括號用於儲存鍵值對資料組成的物件
- 方括號用於儲存鍵值對資料組成的陣列
- 採用物件,陣列方式組織起來的鍵值對可以表示任何結構的資料
- JSON格式是網際網路上主要使用的複雜資料格式之一
- JSON庫是處理JSON格式的python標準庫
- 兩個過程:
- 編碼,將python資料型別準換成json格式的過程
- 解碼,從json格式中解析資料對應到python資料型別的過程
- dumps():將Python資料型別轉換為JSON格式的過程
- loads():將JSON格式字串轉換為Python資料型別
- dump():與dumps()功能一致,輸出到檔案
- load():與loads()功能一致,從檔案讀入
- 列表排序
- list.sort(func)
- func指定排序的方法
- func可以通過lambda函式實現
--snip-- city_list.sort(key= lambda city:city['aqi']) #func:函式為lambda,city為元素 top5_list = city_list[:5] #切片拿取前5個元素 f = open('top5_aqi.json',mode='w',encoding='utf-8') json.dump('top5_list',f,ensure_ascii=False) #第二元素為開啟檔案物件,最後為編碼格式,中文false f.close
-
1 import json 2 3 def process_json_file(filepath): 4 f = open(filepath,mode='r',encoding='utf-8') 5 json.load(f) 6 city_list = json.load(f) 7 return city_list 8 9 def main(): 10 filepath = input('請輸入json檔名稱:') 11 city_list = process_json_file(filepath) 12 city_list.sort(key= lambda city:city['aqi']) #func:函式為lambda,city為元素 13 top5_list = city_list[:5] #切片拿取前5個元素 14 f = open('top5_aqi.json',mode='w',encoding='utf-8') 15 json.dump('top5_list',f,ensure_ascii=False) #第二元素為開啟檔案物件,最後為編碼格式,中文false 16 f.close 17 18 if __name__ == '__main__': 19 main()
View Code - CSV格式是一種通用的、相對簡單的檔案格式,在商業和科學領域廣泛使用
- 規則
- 以行為單位
- 每行表示一條記錄
- 以英文逗號分割每列資料(如果資料為空,逗號也要保留)
- 列名通常放置在問價第一行
- CSV檔案操作
- import csv
- csv.writerow(list)將列表中的元素寫入檔案的一行中
- CSV檔案讀取
- import csv
- csv.reader()將每行記錄作為列表返回
- 使用with語句操作檔案物件
with open('file_name') as somefile: for line in somefile: print(line)
- 使用with語句,不管在處理檔案過程中是否發生發生異常,都能保證with語句執行完畢後關閉檔案,不需要close語句
--snip-- lines.append(list(city_list[0].key())) #使用list拿到city的keys for city in city_list: lines.append(list(city.values())) f = open('aqi.csv','w',encoding='utf-8',newline='') #newline為空表示末尾不加任何字元,否則預設加空行 writer = csv.writer(f) for line in lines: writer.writerow(line) --snip--
1 import json 2 import csv 3 def process_json_file(filepath): 4 f = open(filepath,mode='r',encoding='utf-8') 5 city_list = json.load(f) 6 return city_list 7 8 def main(): 9 filepath = input('請輸入json檔名稱:') 10 city_list = process_json_file(filepath) 11 city_list.sort(key= lambda city:city['aqi']) #func:函式為lambda,city為元素 12 lines = [] 13 lines.append(list(city_list[0].key())) #使用list拿到city的keys 14 for city in city_list: 15 lines.append(list(city.values())) 16 f = open('aqi.csv','w',encoding='utf-8',newline='') #newline為空表示末尾不加任何字元,否則預設加空行 17 writer = csv.writer(f) 18 for line in lines: 19 writer.writerow(line) 20 21 if __name__ == '__main__': 22 main()View Code
- OS模組
- OS模組提供了與系統、目錄操作相關的功能,不受平臺限制
- os.remove():刪除檔案
- os.makedirs():建立多層目錄
- os.rmdir():刪除單級目錄
- os.rename():重新命名檔案
- os.path.isfile():判斷是否為檔案
- os.path.isdir():判斷是否為目錄
- os.path.join():連結目錄,如path1連結path2為path1/path2
- os.path.splitext():將檔案分割成檔名與副檔名,如分割tmp.txt為tmp和.txt
import csv import os def process_json_file(filepath): #解碼json檔案 # f = open(filepath,mode='r',encoding='utf-8') # city_list = json.load(f) # return city_list with open(filepath,mode='r',encoding='utf-8') as f: #with語句不需要關閉檔案 city_list =json.load(f) print(city_list) def process_csv_file(filepath): with open('filepath',mode='r',encoding='utf-8',newline='') as f: reader = csv.reader(f) for row in reader: print(','.jion(row)) #通過逗號連線語句,.jion
1 import json 2 import csv 3 import os 4 def process_json_file(filepath): #解碼json檔案 5 # f = open(filepath,mode='r',encoding='utf-8') 6 # city_list = json.load(f) 7 # return city_list 8 with open(filepath,mode='r',encoding='utf-8') as f: #with語句不需要關閉檔案 9 city_list =json.load(f) 10 print(city_list) 11 def process_csv_file(filepath): 12 with open('filepath',mode='r',encoding='utf-8',newline='') as f: 13 reader = csv.reader(f) 14 for row in reader: 15 print(','.jion(row)) #通過逗號連線語句,.jion 16 17 def main(): 18 filepath = input('請輸入json檔名稱:') 19 filename,file_ext = os.path.splitext(filepath) 20 if file_ext == '.json': 21 process_json_file(filepath) 22 elif file_ext == '.csv': 23 process_csv_file(filepath) 24 else: 25 print('不支援檔案格式!') 26 27 if __name__ == '__main__': 28 main()
View Code
網路爬蟲:
- 自動爬去網際網路資訊程式;利用網際網路資料進行分析、開發產品
- 步驟
- 通過網路連結獲取網頁內容(字串)
- 對獲得的網頁內容進行處理
requests模組
- requests模組時一個簡潔且簡單的處理HTTP請求工具,支援豐富的連結訪問功能,包括url獲取,HTTP會話,Cookie記錄等
- requests網頁請求
- get():對應HTTP的GET方式
- post():對應HTTP的POST方式,用於傳遞使用者資料
- requests物件屬性
- status_code:HTTP請求的返回狀態,200表示連結成功,400表示失敗
- text:HTTP相應內容的字串形式,即URL 對應的頁面內容
- 更多方法參考:https://doc.python-requests.org/
import requests def get_html_text(url): """返回url的文字""" r = requests.get(url,timeout =30) #print(r.status_code) #顯示狀態,200為連結ok return r.text #獲取文字 def main(): city_pinyin = input('請輸入城市拼音:') url = 'http://pm25.in/'+city_pinyin url_text = get_html_text(url) #print(url_text) #屬性名r.text d呼叫為url.text aqi_div='''<div class="span12 data"> <div class="span1"> <div class="value"> ''' #注意複製範圍,一直取值到數字的前面,可能會有空格 index = url_text.find(aqi_div) begin_index = index +len(aqi_div) #從開始索引號'<'加上文字長度 end_index = begin_index + 2 #再獲取2位為AQI值 aqi_value = url_text[begin_index: end_index] print('空氣質量為:{}'.format(aqi_value)) if __name__ == '__main__': main()
網頁解析
-
解析器輸出的樹是由DOM元素和屬性節點組成的。DOM的全稱為:Document Object Model。它是HTML文件的物件化描述,也是HTML元素與外界(如Javascript)的介面。 DOM與標籤有著幾乎一一對應的關係,如下: <html> <body> <p>hello world</p> <div><img src="aa.png"/></div> </body> </html>
- beautifulSoup解析網站(用於解析HTML或XML)
- pip install beautifulsoup4
- import bs4
- 步驟
- 建立BeautifulSoup物件
- 查詢節點
- find, 找到第一個滿足條件的節點
- find_all,找到所有滿足條件的節點
- 例:建立BeautifulSoup物件
bs = BeautifulSoup( url, html_parser, 指定解析器 #一般預設lxml encoding 指定編碼格式(確保和網頁編碼格式一致) #如果不一致會出現亂碼 )
- 查詢節點
- <a href='a.html' class='a_link'>next page</a>
- 可按節點型別、屬性或內容訪問
- 按型別查詢節點
- bs.find_all('a') #查詢到所有a標籤
- 按屬性查詢節點
- bs.find_all('a',href='a.html') #查詢a標籤,到所有符合a.html屬性
- bs.find_all('a',href='a.html',string='next page')
- bs.find_all('a',class_='a.link') #注意:是class_
- 或者bs.find_all('a',{'class':'a_link'})
import requests from bs4 import BeautifulSoup def get_city_aqi(city_pinyin): url = 'http://pm25.in/'+city_pinyin r = requests.get(url,timeout=30) bs = BeautifulSoup(r.text,'lxml') #bs = BeautifulSoup.find_all('div','span') div_list= bs.find_all('div',{'class':'span1'}) #遺漏 city_AQI=[] for i in range(8): div_content = div_list[i] #對其list進行遍歷 aqi = div_content.find('div',{'class':'value'}).text.strip() #AQI = bs.find_all('div','value').text.strip() #應以鍵值對出現 caption = div_content.find('div',{'class':'caption'}).text.strip() #city_AQI = city_AQI.append((caption, aqi)) city_AQI.append((caption, aqi)) return city_AQI def main(): city_pinyin = input('請輸入城市拼音:') city_aqi =get_city_aqi(city_pinyin) print(city_aqi) if __name__ == '__main__': main()
遍歷城市
1 import requests 2 from bs4 import BeautifulSoup 3 4 def get_city_aqi(city_pinyin): 5 url = 'http://pm25.in/'+city_pinyin 6 r = requests.get(url,timeout=30) 7 bs = BeautifulSoup(r.text,'lxml') 8 div_list= bs.find_all('div',{'class':'span1'}) 9 city_AQI=[] 10 for i in range(8): 11 div_content = div_list[i] 12 aqi = div_content.find('div',{'class':'value'}).text.strip() 13 caption = div_content.find('div',{'class':'caption'}).text.strip() 14 city_AQI.append((caption, aqi)) 15 return city_AQI 16 17 def get_all_cities(): 18 url = 'http://pm25.in/' 19 city_list = [] 20 r = requests.get(url, timeout=30) 21 bs = BeautifulSoup(r.text, 'lxml') 22 city_all_name = bs.find_all('div', {'class': 'bottom'})[1] 23 city_link_list = city_all_name.find_all('a') 24 #for i in city_all_name: 此段只要一個bottom元素,將無法輸出 25 for city_link in city_link_list: 26 city_name = city_link.text 27 city_pinyin = city_link['href'][1:] 28 #r = city_all_name[1] 29 #city_name = r.find('div',{'href':'city_link'}).text.strip() 30 #city_link = r.find('div',{'href':'city_link'})[1:] 31 city_list.append((city_name,city_pinyin)) 32 return city_list 33 34 def main(): 35 city_list = get_all_cities() 36 for city in city_list: 37 city_name =city[0] 38 city_pinyin = city[1] 39 city_aqi =get_city_aqi(city_pinyin) 40 print(city,city_aqi) 41 42 if __name__ == '__main__': 43 main()View Code
--snip-- def get_all_cities(): url = 'http://pm25.in/' city_list = [] r = requests.get(url, timeout=30) bs = BeautifulSoup(r.text, 'lxml') city_all_name = bs.find_all('div', {'class': 'bottom'})[1] city_link_list = city_all_name.find_all('a') #尋找所有bottom下的a標籤 for city_link in city_link_list: city_name = city_link.text #取city_link文字 city_pinyin = city_link['href'][1:] #取其‘/’後的數字 city_list.append((city_name,city_pinyin)) return city_list def main(): city_list = get_all_cities() for city in city_list: #對獲取列表進行遍歷輸出 city_name =city[0] city_pinyin = city[1] city_aqi =get_city_aqi(city_pinyin) print(city,city_aqi) #注意為city,city_list將重複報錯 if __name__ == '__main__': main()
字串加列表 ‘abc’+[1,2,3]轉換為['abc']+[1,2,3]
存入轉換為CSV格式
1 import requests 2 from bs4 import BeautifulSoup 3 import csv 4 5 def get_city_aqi(city_pinyin): 6 url = 'http://pm25.in/'+city_pinyin 7 r = requests.get(url,timeout=30) 8 bs = BeautifulSoup(r.text,'lxml') 9 div_list= bs.find_all('div',{'class':'span1'}) 10 city_AQI=[] 11 for i in range(8): 12 div_content = div_list[i] 13 aqi = div_content.find('div',{'class':'value'}).text.strip() 14 caption = div_content.find('div',{'class':'caption'}).text.strip() 15 city_AQI.append(aqi) 16 return city_AQI 17 18 def get_all_cities(): 19 url = 'http://pm25.in/' 20 city_list = [] 21 r = requests.get(url, timeout=30) 22 bs = BeautifulSoup(r.text, 'lxml') 23 city_all_name = bs.find_all('div', {'class': 'bottom'})[1] 24 city_link_list = city_all_name.find_all('a') 25 for city_link in city_link_list: 26 city_name = city_link.text 27 city_pinyin = city_link['href'][1:] 28 city_list.append((city_name,city_pinyin)) 29 return city_list 30 31 def main(): 32 city_list = get_all_cities() 33 header = ['City','AQI','PM2.5/1H','PM10/H','CO/H','NO2/H','O3/1H','O3/8H','SO2/H',] #指定列名 34 with open('china_city_AQI.csv','w',encoding='utf-8',newline='') as f: 35 writer = csv.writer(f) 36 writer.writerow(header) 37 for i,city in enumerate(city_list): #enumerate科學計數法 38 if (i+1)%10 ==0: #實時檢視處理進度 39 print('已處理{}條記錄,共{}記錄'.format(i+1,len(city_list))) 40 city_name = city[0] 41 city_pinyin = city[1] 42 city_aqi = get_city_aqi(city_pinyin) 43 row= [city_name]+city_aqi #字串轉換為列表格式[] 44 writer.writerow(row) 45 46 if __name__ == '__main__': 47 main()View Code
--snip-- def main(): city_list = get_all_cities() header = ['city','AQI','PM2.5/1H','PM10/H','CO/H','NO2/H','O3/1H','O3/8H','SO2/H'] #指定列名 with open('china_city_AQI.csv','w',encoding='utf-8',newline='') as f: writer = csv.writer(f) writer.writerow(header) for i,city in enumerate(city_list): #enumerate科學計數法 if (i+1)%10 ==0: print('已處理{}條記錄,共{}記錄'.format(i+1,len(city_list))) city_name = city[0] city_pinyin = city[1] city_aqi = get_city_aqi(city_pinyin) row= [city_name]+city_aqi writer.writerow(row) if __name__ == '__main__': main()
Pandas庫:
-
- 是一個結構化資料的工具集
- 基礎為Numpy,提供了高效能的矩陣運算
- 應用,資料探勘,資料分析
- 學生成績分析、股票資料分析
- 提供資料清洗功能
- Pandas的資料結構(Series)
- 類似一維陣列的物件
- 通過list構建Series
- ser_obj = pd.Series(range(10))
- 例:
- 由資料和索引組成
- 索引在左,資料在右
- 索引是自動建立的
- 獲取資料和索引
- ser_obj.index,ser_obj.values
- 預覽資料
- ser_obj.head(n) #輸出資料前幾條資料
- wer_obj.tail(n) #資料資料後幾條資料
- 例:
- 通過索引獲取資料
- ser_obj[idx]
- 索引與資料的對應關係仍保持在陣列的運算的結果中國
- 通過dict構建Series
- name屬性
- ser_obj.name, ser_obj.index.name
- DataFrame
- 類似多維陣列、表格資料(如,Excel,R中的data.frame
- 每列資料可以是不同型別,what about ndarray?
- 索引包括列索引和行索引
- 通過ndarray構建DataFrame
- 通過dict構建DataFrame
- 通過索引獲取列資料(Series型別)
- df_obj[col_idx]或df_obj.col_idx
- 增加列資料,類似dict新增key-value
- df_obj[new_col_idx] = data
- 刪除列
- del df_obj[col_idx]
- 索引操作
- DataFrame索引
- 列索引
- df_obj[ 'label' ] #label為標籤名。。。
- 不連續索引
- df_obj[[ 'label1', 'label2' ]] #中間的[]表示傳進去的的為列表
import pandas as pd def main(): aqi_data = pd.read_csv('china_city_AQI.csv') #print(aqi_data.head(5)) #print(aqi_data['AQI']) print(aqi_data[['city','AQI']]) #中間的中括號為列表 if __name__ == '__main__': main()
View Code
- df_obj[[ 'label1', 'label2' ]] #中間的[]表示傳進去的的為列表
- 列索引
- DataFrame索引
- 排序
- sort_index,索引排序
- 對DataFrame操作時注意軸方向
- 按值排序
- sort_values(by = 'label') #label為標籤名 AQI。。。
- sort_index,索引排序
- 常用統計計算
- sum,mean,max,min.....
- axis=0按列統計,axis=1 按行統計
- skipna排除缺失值,預設為True
- idmax,idmin,cumsum
- 統計描述
- describe產生多個統計資料
- 常用統計計算和描述
- count:非NA值得數量
- describe:針對series或各DataFrame列計算彙總統計
- min,max:計算最小值,最大值
- argmin,argmax:計算能夠獲取到最小值和最大值的索引位置(整數)
- idxmin,idxmax:計算能夠獲取到最小值和最大值的索引值
- quantile:計算樣本的分數位(0到1)
- sum:值得總和
- mean:值得平均數
- median:值的算術中位數(50%分位數)
- mad:根據平均值計算平均絕對離差
- var:樣本值的方差
- std:樣本值的標準差
import pandas as pd def main(): aqi_data = pd.read_csv('china_city_AQI.csv') print('基本資訊:') print(aqi_data.info()) print('資料預覽:') print(aqi_data.head()) #基本統計 print('AQI最大值:', aqi_data['AQI'].max()) print('AQI最大值:', aqi_data['AQI'].min()) print('AQI最大值:', aqi_data['AQI'].mean()) #top10 top10_cities= aqi_data.sort_values(by=['AQI']).head(10) print('空氣質量最好的10個城市:',top10_cities) #bottom10 #bottom10_cities = aqi_data.sort_values(by=['AQI']).tail(10) bottom10_cities = aqi_data.sort_values(by=['AQI'],ascending= False).head(10) #同理上述寫法,降序排列 print('空氣質量最差的10個城市:', bottom10_cities) #儲存csv檔案 top10_cities.to_csv('top10_aqi.csv',index = False) #index為不需要序列號 bottom10_cities.to_csv('top10_aqi.csv',index = False) if __name__ == '__main__': main()
Pandas資料清洗
- 處理缺失資料
- dropna()丟棄缺失資料
- fillna()填充缺失資料
- 資料過濾
- df[filter_condition]根據filter_condition對資料進行過濾
1 import pandas as pd 2 3 def main(): 4 aqi_data = pd.read_csv('china_city_AQI.csv') 5 print('基本資訊:') 6 print(aqi_data.info()) 7 print('資料預覽:') 8 print(aqi_data.head()) 9 10 #資料清洗,只保留AQI>0的資料 11 # filter_condition = aqi_data['AQI'] > 0 12 # clean_data = aqi_data[filter_condition]或者 13 clean_aqi_data = aqi_data[aqi_data['AQI'] > 0] 14 15 #基本統計 16 print('AQI最大值:', aqi_data['AQI'].max()) 17 print('AQI最大值:', aqi_data['AQI'].min()) 18 print('AQI最大值:', aqi_data['AQI'].mean()) 19 20 #top10 21 top10_cities= clean_aqi_data.sort_values(by=['AQI']).head(10) 22 print('空氣質量最好的10個城市:',top10_cities) 23 #bottom10_cities = clean_aqi_data.sort_values(by=['AQI']).tail(10)或者 24 bottom10_cities = clean_aqi_data.sort_values(by=['AQI'],ascending= False).head(10) #同理上述寫法,降序排列 25 print('空氣質量最差的10個城市:', bottom10_cities) 26 27 if __name__ == '__main__': 28 main()View Code
--snip-- #資料清洗,只保留AQI>0的資料 # filter_condition = aqi_data['AQI'] > 0 # clean_data = aqi_data[filter_condition]或者 clean_aqi_data = aqi_data[aqi_data['AQI'] > 0] --snip--
Pandas資料視覺化
- pandas提供了內建的繪圖功能(基於matplotlib)
- plot(kind,x,y,title,figsize) #kind可以是’line’, ‘bar’, ‘barh’, ‘kde’
- x,y橫縱座標對應的資料列
- title:影象名
- figsize:影象尺寸
- 參照:https://blog.csdn.net/hustqb/article/details/54410670
- 儲存圖片:plt.savefig()
- 更多例子:http://pandas.pydata.org/pandas-docs/stable/visualization.html
import pandas as pd def main(): aqi_data = pd.read_csv('china_city_AQI.csv') print('基本資訊:') print(aqi_data.info()) print('資料預覽:') print(aqi_data.head()) #基本統計 print('AQI最大值:', aqi_data['AQI'].max()) #top10 top10_cities= aqi_data.sort_values(by=['AQI']).head(10) print('空氣質量最好的10個城市:',top10_cities) #bottom10 #bottom10_cities = aqi_data.sort_values(by=['AQI']).tail(10) bottom10_cities = aqi_data.sort_values(by=['AQI'],ascending= False).head(10) #同理上述寫法,降序排列 print('空氣質量最差的10個城市:', bottom10_cities) #儲存csv檔案 top10_cities.to_csv('top10_aqi.csv',index = False) #index為不需要序列號 bottom10_cities.to_csv('bottom10_aqi.csv',index = False) if __name__ == '__main__': main()