這是《Python編程:從入門到實(shí)踐》的第二個(gè)實(shí)踐項(xiàng)目的第二部分匿醒,對(duì)應(yīng)第16章场航,對(duì)CSV和JSON格式的數(shù)據(jù)繪制圖表。
1. 讀取csv文件
這里的csv文件記錄的是某地的天氣廉羔,包括氣象站的編碼溉痢、名稱、日期憋他、降水量孩饼、最高氣溫和最低氣溫。
讀取csv文件表頭竹挡,并獲得列名的索引镀娶。
import csv
filename = 'data/sitka_weather_07-2018_simple.csv'
### 讀取csv文件頭
with open(filename) as f: #f是一個(gè)表示文件的對(duì)象
reader = csv.reader(f) #創(chuàng)建一個(gè)與該文件相關(guān)聯(lián)的閱讀器對(duì)象
header_row = next(reader) #返回文件中的下一行
print(header_row) #將逗號(hào)分隔的每一項(xiàng)數(shù)據(jù)作為一個(gè)元素存儲(chǔ)在列表中
#['STATION', 'NAME', 'DATE', 'PRCP', 'TAVG', 'TMAX', 'TMIN']
for index, column_header in enumerate(header_row):
print(index, column_header) #enumerate()獲取每個(gè)元素的索引及其值
01_csv_headers.JPG
其它的一些讀取文件內(nèi)容的方法。
#open()接受一個(gè)參數(shù)揪罕,即要打開的文件名梯码,返回一個(gè)表示文件的對(duì)象宝泵;with在不需要訪問文件后將其關(guān)閉
with open(filename) as f:
contents = f.read() #方法read()讀取文件的內(nèi)容,作為一個(gè)長(zhǎng)字符串賦值給contents
print(contents)
with open(filename) as f:
for line in f: #逐行讀取文件內(nèi)容
print(line)
with open(filename) as f:
lines = f.readlines() #方法readlines()從文件中讀取每一行忍些,并將其存儲(chǔ)在一個(gè)列表中
for line in lines:
print(line)
提取csv文件的某列內(nèi)容鲁猩。
import csv
filename = 'data/sitka_weather_07-2018_simple.csv'
with open(filename) as f: #f是一個(gè)表示文件的對(duì)象
reader = csv.reader(f) #創(chuàng)建一個(gè)與該文件相關(guān)聯(lián)的閱讀器對(duì)象
header_row = next(reader) #返回文件中的下一行
#從文件中獲取最高溫度
highs = []
for row in reader: #遍歷文件余下的各行,閱讀器從其停留的地方繼續(xù)往下讀取csv
high = int(row[5]) #默認(rèn)是字符串罢坝,轉(zhuǎn)換為整數(shù)
highs.append(high)
print(highs)
2. 從csv文件讀取數(shù)據(jù)并繪圖
將最高溫度畫成折線圖廓握。
import csv
import matplotlib.pyplot as plt
filename = 'data/sitka_weather_07-2018_simple.csv'
#讀取csv文件并獲得最高溫度
with open(filename) as f: #f是一個(gè)表示文件的對(duì)象
reader = csv.reader(f) #創(chuàng)建一個(gè)與該文件相關(guān)聯(lián)的閱讀器對(duì)象
header_row = next(reader) #返回文件中的下一行
highs = []
for row in reader: #遍歷文件余下的各行,閱讀器從其停留的地方繼續(xù)往下讀取csv
high = int(row[5]) #默認(rèn)是字符串嘁酿,轉(zhuǎn)換為整數(shù)
highs.append(high)
#繪制溫度圖表
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.plot(highs, c='red')
#設(shè)置圖形格式
plt.title("Daily high temperatures, July 2018", fontsize=24)
plt.xlabel('', fontsize=16)
plt.ylabel("Temperature (F)", fontsize=16)
plt.tick_params(axis='both', which='major', labelsize=16)
#plt.show()
plt.savefig('03_csv_plotting.png', bbox_inches='tight')
03_csv_plotting.png
在x軸表示日期隙券。
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'data/sitka_weather_2018_simple.csv'
#讀取csv文件并獲得日期和最高溫度
with open(filename) as f: #f是一個(gè)表示文件的對(duì)象
reader = csv.reader(f) #創(chuàng)建一個(gè)與該文件相關(guān)聯(lián)的閱讀器對(duì)象
header_row = next(reader) #返回文件中的下一行
dates, highs = [], []
for row in reader: #遍歷文件余下的各行,閱讀器從其停留的地方繼續(xù)往下讀取csv
current_date = datetime.strptime(row[2], '%Y-%m-%d') #將字符串轉(zhuǎn)換為表示日期的對(duì)象
high = int(row[5]) #默認(rèn)是字符串闹司,轉(zhuǎn)換為整數(shù)
dates.append(current_date)
highs.append(high)
#繪制溫度圖表
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.plot(dates, highs, c='red')
#設(shè)置圖形格式
ax.set_title("Daily high temperatures - 2018", fontsize=20)
ax.set_xlabel('', fontsize=13)
fig.autofmt_xdate() #繪制傾斜的日期標(biāo)簽
ax.set_ylabel("Temperature (F)", fontsize=13)
ax.tick_params(axis='both', which='major', labelsize=13)
#plt.show()
plt.savefig('04_csv_datetime.png', bbox_inches='tight')
04_csv_datetime.png
增加圖表內(nèi)容娱仔。
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'data/sitka_weather_2018_simple.csv'
#讀取csv文件并獲得日期、最高溫度游桩、最低溫度
with open(filename) as f: #f是一個(gè)表示文件的對(duì)象
reader = csv.reader(f) #創(chuàng)建一個(gè)與該文件相關(guān)聯(lián)的閱讀器對(duì)象
header_row = next(reader) #返回文件中的下一行
dates, highs, lows = [], [], []
for row in reader: #遍歷文件余下的各行牲迫,閱讀器從其停留的地方繼續(xù)往下讀取csv
current_date = datetime.strptime(row[2], '%Y-%m-%d') #將字符串轉(zhuǎn)換為表示日期的對(duì)象
high = int(row[5]) #默認(rèn)是字符串,轉(zhuǎn)換為整數(shù)
low = int(row[6])
dates.append(current_date)
highs.append(high)
lows.append(low)
#繪制溫度圖表
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.plot(dates, highs, c='red', linewidth=1, alpha=0.8)
ax.plot(dates, lows, c='blue', linewidth=1, alpha=0.8)
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
#設(shè)置圖形格式
ax.set_title("Daily high temperatures - 2018", fontsize=20)
ax.set_xlabel('', fontsize=13)
fig.autofmt_xdate() #繪制傾斜的日期標(biāo)簽
ax.set_ylabel("Temperature (F)", fontsize=13)
ax.tick_params(axis='both', which='major', labelsize=13)
#plt.show()
plt.savefig('05_csv_adding.png', bbox_inches='tight')
05_csv_adding.png
3. 應(yīng)對(duì)csv文件中的缺失值
如果csv文件中有缺失值借卧,讀取時(shí)會(huì)出現(xiàn)一個(gè)異常ValueError盹憎。
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'data/death_valley_2018_simple.csv'
#讀取csv文件并獲得日期、最高溫度铐刘、最低溫度
with open(filename) as f: #f是一個(gè)表示文件的對(duì)象
reader = csv.reader(f) #創(chuàng)建一個(gè)與該文件相關(guān)聯(lián)的閱讀器對(duì)象
header_row = next(reader) #返回文件中的下一行
dates, highs, lows = [], [], []
for row in reader: #遍歷文件余下的各行陪每,閱讀器從其停留的地方繼續(xù)往下讀取csv
current_date = datetime.strptime(row[2], '%Y-%m-%d') #將字符串轉(zhuǎn)換為表示日期的對(duì)象
try: #如果下面的代碼運(yùn)行沒有問題,將跳過except
high = int(row[4]) #默認(rèn)是字符串镰吵,轉(zhuǎn)換為整數(shù)
low = int(row[5])
except ValueError: #如果導(dǎo)致了錯(cuò)誤檩禾,會(huì)查找匹配的except代碼塊并運(yùn)行;后面的程序還能繼續(xù)運(yùn)行
print(f"Missing data for {current_date}") #或者使用pass靜默失敗
else: #try下面的代碼執(zhí)行成功后執(zhí)行else代碼塊
dates.append(current_date)
highs.append(high)
lows.append(low)
#繪制溫度圖表
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.plot(dates, highs, c='red', linewidth=1, alpha=0.8)
ax.plot(dates, lows, c='blue', linewidth=1, alpha=0.8)
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
#設(shè)置圖形格式
ax.set_title("Daily high and low temperatures - 2018\nDeath Valley, CA",
fontsize=18)
ax.set_xlabel('', fontsize=13)
fig.autofmt_xdate() #繪制傾斜的日期標(biāo)簽
ax.set_ylabel("Temperature (F)", fontsize=13)
ax.tick_params(axis='both', which='major', labelsize=13)
#plt.show()
plt.savefig('06_csv_valueerror.png', bbox_inches='tight')
06_csv_valueerror.png
4. 讀取json文件
這個(gè).json文件直接打開是這樣的疤祭。
07 eq_data_1_day_m1.JPG
讀取這個(gè)文件盼产,然后將其轉(zhuǎn)換成更易讀的格式。
import json
#讀取json文件
filename = 'data/eq_data_1_day_m1.json'
with open(filename) as f:
all_eq_data = json.load(f)
#保存json文件
readable_file = 'data/readable_eq_data.json'
with open(readable_file, 'w') as f:
json.dump(all_eq_data, f, indent=4)
#indent=4使用與數(shù)據(jù)結(jié)構(gòu)匹配的縮進(jìn)來設(shè)置數(shù)據(jù)格式
現(xiàn)在直接打開是這樣的勺馆。
07 readable_eq_data.JPG
需要提取地震的位置辆飘、震級(jí)等信息。
import json
# 讀取json文件
filename = 'data/eq_data_1_day_m1.json'
with open(filename) as f:
all_eq_data = json.load(f)
# 提取與鍵'features'相關(guān)聯(lián)的數(shù)據(jù)谓传,是一個(gè)列表蜈项,列表元素為字典,表示每一次地震
all_eq_dicts = all_eq_data['features']
print(len(all_eq_dicts))
# 提取震級(jí)
mags = []
for eq_dict in all_eq_dicts:
mag = eq_dict['properties']['mag']
mags.append(mag)
print(mags[:10])
# 提取位置信息
mags, titles, lons, lats = [], [], [], []
for eq_dict in all_eq_dicts:
mag = eq_dict['properties']['mag']
title = eq_dict['properties']['title']
lon = eq_dict['geometry']['coordinates'][0] #經(jīng)度
lat = eq_dict['geometry']['coordinates'][1] #緯度
mags.append(mag)
titles.append(title)
lons.append(lon)
lats.append(lat)
print(mags[:10])
print(titles[:2])
print(lons[:5])
print(lats[:5])
08_json_extracting.JPG
5. 從json文件讀取數(shù)據(jù)并繪圖
感覺這一部分書上講的有點(diǎn)不清楚续挟。需要下載安裝pandas紧卒。
python -m pip install --user pandas
使用plotly繪制散點(diǎn)圖。
import json
import plotly.express as px
# 讀取json文件
filename = 'data/eq_data_1_day_m1.json'
with open(filename) as f:
all_eq_data = json.load(f)
# 提取位置信息
all_eq_dicts = all_eq_data['features']
mags, titles, lons, lats = [], [], [], []
for eq_dict in all_eq_dicts:
mag = eq_dict['properties']['mag']
title = eq_dict['properties']['title']
lon = eq_dict['geometry']['coordinates'][0] #經(jīng)度
lat = eq_dict['geometry']['coordinates'][1] #緯度
mags.append(mag)
titles.append(title)
lons.append(lon)
lats.append(lat)
# 繪制震級(jí)散點(diǎn)圖
fig = px.scatter(
x=lons,
y=lats,
labels={'x':'經(jīng)度','y':'緯度'},
range_x=[-200, 200],
range_y=[-90, 90],
width=800,
height=800,
title='全球地震散點(diǎn)圖'
)
fig.write_html('09_json_plotly.html')
fig.show()
09_json_plotly.JPG
使用pandas诗祸,并增加圖像細(xì)節(jié)跑芳。
import json
import plotly.express as px
import pandas as pd
# 讀取json文件
filename = 'data/eq_data_30_day_m1.json'
with open(filename) as f:
all_eq_data = json.load(f)
# 提取位置信息
all_eq_dicts = all_eq_data['features']
mags, titles, lons, lats = [], [], [], []
for eq_dict in all_eq_dicts:
mag = eq_dict['properties']['mag']
title = eq_dict['properties']['title']
lon = eq_dict['geometry']['coordinates'][0] #經(jīng)度
lat = eq_dict['geometry']['coordinates'][1] #緯度
mags.append(mag)
titles.append(title)
lons.append(lon)
lats.append(lat)
#創(chuàng)建一個(gè)DataFrame將數(shù)據(jù)封裝起來
data = pd.DataFrame(
data=zip(lons, lats, titles, mags), columns=['經(jīng)度', '緯度', '位置', '震級(jí)']
)
data.head()
# 繪制震級(jí)散點(diǎn)圖
fig = px.scatter(
data,
x='經(jīng)度',
y='緯度',
range_x=[-200, 200],
range_y=[-90, 90],
width=800,
height=800,
title='全球地震散點(diǎn)圖',
size='震級(jí)',
size_max=10, #默認(rèn)20像素轴总,縮放到10
color='震級(jí)', #默認(rèn)數(shù)值從小到大,顏色從藍(lán)到紅再到黃
hover_name='位置', #鼠標(biāo)指向時(shí)顯示的文本
)
fig.write_html('10_json_pandas.html')
fig.show()
10_json_pandas.JPG