文章目录[隐藏]
使用Python模块csv来处理CSV格式存储的天气数据,找出两个地区在一段时间呢的最高温度和最低温度。然后,使用Matplotlib根据下载的数据创建一个图表,展示两个不同地区的温度变换:阿拉斯加州锡特卡和季利夫尼牙死亡谷。然后,使用模块json访问JSON格式存储的地震数据,并使用Plotly绘制一幅散点图,展示这些地震的位置和震级。
CSV文件格式
要在文本文件中存储数据,一个简单方式是将数据作为一系列以逗号分隔的值写入文件。这样的文件称为CSV文件。例如:
"USW00025333","SITKA AIRPORT","AK US","2018-01-01","0.45",,"48","38"
分析CSV文件头
csv模块包含在Python标准库中,可用于分析CSV文件中的数据行。
先查看这个文件的第一行,其中的一系列文件头指出了后续各行包含的是什么样的信息。
import csv
filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
print(header_row)
导入csv。调用csv.reader()并将f对象作为实参赋值给它。从而创建一个与该文件相关联的阅读器对象。这个阅读器对象被赋给了reader。
模块csv包含函数next(),调入它并传入阅读器对象时,将返回文件中的下一行。只调用next()一次,因此得到的是文件第一行数据,其包含文件头。
reader处理文件中以逗号分隔的第一行数据,并将每项数据都作为一个元素存储在列表中。文件头STAION表示数据的气象站的编码。这个文件头的位置表明,每行的第一个值都是气象站编码。NAME气象站名称。DATA日期。TMAX最高气温,TMIN最低气温。
打印文件头及其位置
import csv
filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
for index,column_header in enumerate(header_row):
print(index,column_header)
在循环中,对列表调用了enumerate()来获取每个元素的索引及其值。
提取并读取数据
import csv
filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
highs = []
for row in reader:
high = int(row[5])
highs.append(high)
print(highs)
绘制温度图标
为可视化这些温度数据。首先使用Matplotlib创建一个显示每日最高温度的简单图形。
import csv
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)
filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
highs = []
for row in reader:
high = int(row[5])
highs.append(high)
# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(highs,c='red')
# 设置图形的格式
ax.set_title("2018年7月每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)
plt.show()
模块datetime
读取时间列时,获得的是一个字符串,因此需要将字符串"2018-7-1"转换为一个表示相应日期的对象。为创建一个表示2018年7月1日的对象。可以使用模块datetime中的方法strptime()。
from datetime import datetime
first_data = datetime.strptime('2018-07-01','%Y-%m-%d')
print(first_data)
2018-07-01 00:00:00
首先导入模块datetime中的datetime类,再调用方法strptime(),并将包含所需日期的字符串作为第一个实参。第二个实参告诉Python如何设置日期的格式。在这里,‘%Y-’让Python将字符串中的第一个连字符前面的部分视为四位的年份,'%m-'将第二个连字符前面的部分表示为月份,'%d'让最后一部分视为月份中的一天(1-31)。
方法strptime()可接受各种实参,并根据它们来决定如何解读日期。
实参 | 含义 |
%A | 星期几,如Monday |
%B | 月份名,如January |
%m | 用数表示的月份(01~12) |
%d | 用数表示的月份中的每一天(01~31) |
%Y | 四位的年份,如2022 |
%y | 两位的年份,如22 |
%H | 24小时制度的小时数(00~23) |
%I | 12小时制的小时数(01~12) |
%p | am或pm |
%M | 分钟数(00~59) |
%S | 秒数(00~61) |
在图标中添加日期
可以通过提取日期和最高温度绘图:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)
filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取日期和最高温度
dates,highs = [],[]
for row in reader:
current_date = datetime.strptime(row[2],'%Y-%m-%d')
high = int(row[5])
dates.append(current_date)
highs.append(high)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
# highs = []
# for row in reader:
# high = int(row[5])
# highs.append(high)
# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red')
# 设置图形的格式
ax.set_title("2018年7月每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)
plt.show()
调用fig.autofmt_xdate()来绘制倾斜的日期标签,以免彼此重叠。
涵盖更长的时间
import csv
from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)
filename = './data/sitka_weather_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取日期和最高温度
dates,highs = [],[]
for row in reader:
current_date = datetime.strptime(row[2],'%Y-%m-%d')
high = int(row[5])
dates.append(current_date)
highs.append(high)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
# highs = []
# for row in reader:
# high = int(row[5])
# highs.append(high)
# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red')
# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)
plt.show()
再绘制一个数据系列
添加最低温气温。
import csv
from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)
filename = './data/sitka_weather_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取日期和最高温度和最低温气温。
dates,highs,lows = [],[],[]
for row in reader:
current_date = datetime.strptime(row[2],'%Y-%m-%d')
high = int(row[5])
low = int(row[6])
dates.append(current_date)
highs.append(high)
lows.append(low)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
# highs = []
# for row in reader:
# high = int(row[5])
# highs.append(high)
# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red')
ax.plot(dates,lows,c='blue')
# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)
plt.show()
给图标区域着色
通过着色来呈现每天的温度范围。为此,将使用方法fill_betweem()它将接受一个x值系列和两个y值系列并填充两个y值系列之间的空间。
import csv
from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)
filename = './data/sitka_weather_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取日期和最高温度和最低温气温。
dates,highs,lows = [],[],[]
for row in reader:
current_date = datetime.strptime(row[2],'%Y-%m-%d')
high = int(row[5])
low = int(row[6])
dates.append(current_date)
highs.append(high)
lows.append(low)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
# highs = []
# for row in reader:
# high = int(row[5])
# highs.append(high)
# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red',alpha=0.5)
ax.plot(dates,lows,c='blue',alpha=0.5)
ax.fill_between(dates,highs,lows,facecolor='blue',alpha=0.1)
# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)
plt.show()
alpha指定颜色的透明度。0为完全透明,1表示完全不透明。
fill_between()传递一个x值系列以及两个y值系列。实参facecolor指定填充区域的颜色。
错误检查
偶尔气象站某天数据确实。如果未处理,缺失数据可能引发异常。如果不妥善处理,可能导致程序奔溃。
例如:
import csv
filename = './data/death_valley_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
for index,column_header in enumerate(header_row):
print(index,column_header)
最高温和最低温索引与之前不同。
另外,这个气象站没有记录平均温度。而记录了TOBS,即特定时间点的温度。
为了演示缺失数据时出现的状况:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)
filename = './data/death_valley_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取日期和最高温度和最低温气温。
dates,highs,lows = [],[],[]
for row in reader:
current_date = datetime.strptime(row[2],'%Y-%m-%d')
high = int(row[4])
low = int(row[5])
dates.append(current_date)
highs.append(high)
lows.append(low)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
# highs = []
# for row in reader:
# high = int(row[5])
# highs.append(high)
# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red',alpha=0.5)
ax.plot(dates,lows,c='blue',alpha=0.5)
ax.fill_between(dates,highs,lows,facecolor='blue',alpha=0.1)
# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)
plt.show()
直接对缺失数据的情形做处理。
为此,在从CSV文件中读取值时执行错误检查代码,对可能出现的异常进行处理。如下:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)
filename = './data/death_valley_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取日期和最高温度和最低温气温。
dates,highs,lows = [],[],[]
for row in reader:
current_date = datetime.strptime(row[2],'%Y-%m-%d')
try:
high = int(row[4])
low = int(row[5])
except ValueError:
print(f"Missing data for {current_date}")
else:
dates.append(current_date)
highs.append(high)
lows.append(low)
# for index,column_header in enumerate(header_row):
# print(index,column_header)
# 从文件中获取最高温度
# highs = []
# for row in reader:
# high = int(row[5])
# highs.append(high)
# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red',alpha=0.5)
ax.plot(dates,lows,c='blue',alpha=0.5)
ax.fill_between(dates,highs,lows,facecolor='blue',alpha=0.1)
# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)
plt.show()
使用的很多数据集都可能缺失数据、格式不正确或数据本身不正确,对于这样子的情形,可以使用try-expect-else处理。
在有些情况下,需要使用continue来跳过一些数据,或者使用remove()或del将以提取的数据删除,只要能进行精确而有意义的可视化,采取任何关用的方法都是可以的。
叨叨几句... NOTHING