在文本文件中存储数据,可以将数据作为一系列以逗号分隔的值(CSV)写入文件,这种文件称为CSV文件。例如:
65,43,24,2,4,5,32,,,24,0.0,132
CSV文件对人来说比较麻烦阅读,但程序可以轻松提取并处理其中的数据。
1、分析CSV文件头
csv模块在Python标准库中,可以用于分析CSV文件中的数据行。
import csv
filename = 'sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
print(header)
导入csv模块,打开文件并将文件对象存储在f中。然后调用csv.reader()并将前面存储的文件对象传递给它,从而创建一个与该文件关联的阅读器(reader)对象,并将其保存在reader中。
模块csv中包含next()函数,调用它并将阅读器对象传递给它,将返回文件的下一行。在上述代码中,只调用了一次,因此只得到文件的第一行。
['STATION', 'NAME', 'DATE', 'PRCP', 'TAVG', 'TMAX', 'TMIN']
reader处理文件中的第一行,并将以逗号分隔的数据存储在一个列表中。
文件的格式并非总是一致的,空格和单位可能出现在奇怪的地方。
2、打印文件头及其位置
import csv
filename = 'sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
for index,column in enumerate(header):
print(index,column)
对列表使用enumerate()函数来获取每个元素以及索引。
0 STATION
1 NAME
2 DATE
3 PRCP
4 TAVG
5 TMAX
6 TMIN
由此可以知道每一列存储的是什么数据,如STATION存储在第一列。
3、提取并读取数据
接下来尝试读取每天的TMAX数据:
import csv
filename = 'sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax = []
for row in reader:
tmax.append(row[5])
print(tmax)
创建空列表用于存储TMAX数据,遍历文件中的所有行。阅读器从其停留的地方继续往下读取CSV文件,每次都自动返回当前所处位置的下一行。由于已经读取了文件头,因此循环从第二行开始。每次循环都索引[5]找到TMAX列的数据并添加到列表。
['62', '58', '70', '70', '67', '59', '58', '62', '66', '59', '56', '63', '65', '58', '56', '59', '64', '60', '60', '61', '65', '65', '63', '59', '64', '65', '68', '66', '64', '67', '65']
继续将这些字符串数据转换为数字,方便使用:
import csv
filename = 'sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax = []
for row in reader:
t = int(row[5])
tmax.append(t)
print(tmax)
[62, 58, 70, 70, 67, 59, 58, 62, 66, 59, 56, 63, 65, 58, 56, 59, 64, 60, 60, 61, 65, 65, 63, 59, 64, 65, 68, 66, 64, 67, 65]
4、绘制图表
使用matplolib创建一个显示每日最高气温TMAX的简单图表:
import csv
import matplotlib.pyplot as plt
filename = 'sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax = []
for row in reader:
t = int(row[5])
tmax.append(t)
#绘制图表
fig = plt.figure(dpi=128, figsize=(10,6))
plt.plot(tmax,c='r')
#设置样式
plt.title("Daily max temperatures", fontsize=24)
plt.xlabel('',fontsize=16)
plt.ylabel('Temperature(F)',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
将最高气温列表传递给plot(),并将数据点绘制为红色(c='r')。设置标题及其字体大小。设置x轴标签及其大小,y轴标签及其大小。设置坐标轴刻度参数 。
5、模块datetime
接下来在图表中添加日期。
"USW00025333","SITKA AIRPORT, AK US","2018-07-01","0.25",,"62","50"
日期在第三列:“2018-07-01”,为了将字符串转换为表示日期的对象,可以使用模块datetime中的方法strptime()。
strptime()的用法:
>>> from datetime import daetime
>>> first_date = datetime.strptime('2014-02-21', '%Y-%m-%d')
>>> print(first_date)
2014-02-21 00:00:00
首先导入模块datetime中的datetime类,然后调用方法strptime(),并将日期字符串作为实参。第二个参数表示如何设置日期格式。%Y-让Python将第一个连字符前面的部分设为年份;%m-将第二个连字符前面的部分设为月份;%d将最后一部分设为日期。
方法strptime()可以接收各种参数并根据它们来处理日期字符串:
参数 | 含义 |
%A | 星期的名称,如Monday |
%B | 月份名,如January |
%m | 月份,(01-12) |
%d | 日期,(01-31) |
%Y | 年份,如2016 |
%y | 两位数年份,如16 |
%H | 24小时制的小时(00-23) |
%I | 12小时制的小时(01-12) |
%p | am/pm |
%M | 分钟(00-59) |
%S | 秒数(00-61) |
6、在图表中添加日期
提取最高气温和日期,并将它们传递给plot函数:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax,date = [],[]
for row in reader:
t = int(row[5])
tmax.append(t)
d = datetime.strptime(row[2], "%Y-%m-%d")
date.append(d)
#绘制图表
fig = plt.figure(dpi=128, figsize=(10,6))
plt.plot(date, tmax,c='r')
#设置样式
plt.title("Daily max temperatures", fontsize=24)
plt.xlabel('',fontsize=16)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
将日期字符串(row[2])转换为datetime对象,并将其添加到列表date。将日期列表和最高气温列表传递给plot()。调用fig.autofmt_xdate()来绘制斜的日期标签以免重叠。
7、添加更多的数据
设置号格式后,添加更多的数据来绘制图表。
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'sitka_weather_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax,date = [],[]
for row in reader:
t = int(row[5])
tmax.append(t)
d = datetime.strptime(row[2], "%Y-%m-%d")
date.append(d)
#绘制图表
fig = plt.figure(dpi=128, figsize=(10,6))
plt.plot(date, tmax,c='r')
#设置样式
plt.title("Daily max temperatures - 2018", fontsize=24)
plt.xlabel('',fontsize=16)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
修改读取的文件以及标题:
8、添加数据系列
在上述图表中添加数据文件中的最低气温:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'sitka_weather_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax,tmin,date = [],[],[]
for row in reader:
t = int(row[5])
tmax.append(t)
t = int(row[6])
tmin.append(t)
d = datetime.strptime(row[2], "%Y-%m-%d")
date.append(d)
#绘制图表
fig = plt.figure(dpi=128, figsize=(10,6))
plt.plot(date, tmax,c='r')
plt.plot(date,tmin,c='blue')
#设置样式
plt.title("Daily max and min temperatures - 2018", fontsize=24)
plt.xlabel('',fontsize=16)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
9、给图表区域着色
接着通过给图表着色来呈现每天的气温范围。使用fill_between()方法,该方法接收一个x值系列和一个y系列,并填充两个系列之间的空间:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'sitka_weather_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax,tmin,date = [],[],[]
for row in reader:
t = int(row[5])
tmax.append(t)
t = int(row[6])
tmin.append(t)
d = datetime.strptime(row[2], "%Y-%m-%d")
date.append(d)
#绘制图表
fig = plt.figure(dpi=128, figsize=(10,6))
plt.plot(date, tmax,c='r',alpha=0.5)
plt.plot(date,tmin,c='blue',alpha=0.5)
plt.fill_between(date,tmax,tmin,facecolor='b',alpha=0.1)
#设置样式
plt.title("Daily max and min temperatures - 2018", fontsize=24)
plt.xlabel('',fontsize=16)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
实参alpha指定颜色透明度:alpha为0表示完全透明,1(默认)表示完全不透明。设置为0.5可以让红色和蓝色折线看起来更浅。
调用fill_between()方法,传递date作为x值,传递两个y值:tmax和tmin。参数facecolor指定填充区域的颜色。
10、文件数据缺失或错误
有时候,文件中的数据可能会有缺失值或错误值,这会导致程序不能正常运行。
例如,如果文件中某一行TMAX和TMIN 缺失:
"USW00025333","SITKA AIRPORT, AK US","2018-01-12","0.18",,"",""
会出现报错:
Traceback (most recent call last):
File "tmax_tmin.py", line 12, in <module>
t = int(row[5])
ValueError: invalid literal for int() with base 10: ''
原因是无法将空字符串(' ')转换为整数。为了解决这个问题,在文件读取时执行错误检查代码,对数据可能出现的问题进行处理:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'sitka_weather_2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header = next(reader)
tmax,tmin,date = [],[],[]
for row in reader:
try:
maxt = int(row[5])
mint = int(row[6])
d = datetime.strptime(row[2], "%Y-%m-%d")
except ValueError:
print(d,' missing data')
else:
tmax.append(maxt)
tmin.append(mint)
date.append(d)
#绘制图表
fig = plt.figure(dpi=128, figsize=(10,6))
plt.plot(date, tmax,c='r',alpha=0.5)
plt.plot(date,tmin,c='blue',alpha=0.5)
plt.fill_between(date,tmax,tmin,facecolor='b',alpha=0.1)
#设置样式
plt.title("Daily max and min temperatures - 2018", fontsize=24)
plt.xlabel('',fontsize=16)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
缺失项那行会引发异常,执行打印代码。之后继续处理下一行数据。
2018-01-11 00:00:00 missing data