导入模块 csv ,将要使用的文件的名称赋给 filename。接下来,打开这个文件,并将返回的文件对象赋给 f 。
import csv
# 将文件放在工程文件夹,在同一个路径下,不需要添加绝对路径
filename = 'sitka_weather_07-2018_simple.csv'
# 注意一点,接下来的操作是在打开这份文件的基础上进行的,所以要注意缩进
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader) # next()返回文件中的下一行
print(header_row) # 打印表头
# 获取每个元素的索引及其值
for index,column_header in enumerate(header_row):
print(index,column_header)
输出结果:可以看出通过**enumerate()**我们获取元素的索引,以便我们接下来对文件中数据的处理
['STATION', 'NAME', 'DATE', 'PRCP', 'TAVG', 'TMAX', 'TMIN']
0 STATION
1 NAME
2 DATE
3 PRCP
4 TAVG
5 TMAX
6 TMIN
当我们通过上述方法获取文件中的表头以及索引号之后,接下来就是对文件数据的处理。
在这里对 row 感觉有点疑惑,在循环中表示行,但在提取数据时是列。
--snip--
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取最高的温度
highs = []
for row in reader: # 遍历文件中余下的各行
high = int(row[5]) # row()默认是列
highs.append(high)
print(highs)
输出结果:通过列表形式输出,这样就可以可视化这些数据了
[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]
其中包含最低、最高温度两条折线图,以及他们之间的区域
在这里关于 Matplotlib 制图就不再赘述
import csv
# datetime模块中的类
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'sitka_weather_2018_simple.csv'
with open(filename) as f:
--snip--
# 从文件中获取日期、最高温度和最低温度
dates, highs, lows = [], [], []
# 书本306模块date设置时间日期格式的实参
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)
# 根据最高温度和最低温度绘制图形
plt.style.use('seaborn') # 设置图表的内置的样式
fig, ax = plt.subplots()
# alpha指定颜色的透明度
ax.plot(dates, highs, c='red', alpha=0.5)
ax.plot(dates, lows, c='blue', alpha=0.5)
# facecolor填充颜色
ax.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
# 设置图形的格式
ax.set_title("2018DTMAX-MIN")
ax.set_xlabel('', fontsize=16)
# 绘制倾斜的 X 轴日期标签,以免重叠
fig.autofmt_xdate()
ax.set_ylabel('T(F)', fontsize=16)
# 设置刻度的样式和大小
ax.tick_params(axis='both', which='major', labelsize=16)
plt.show()
添加日期是通过模块 datetime 中的方法 strptime()
方法 **strptime()**可接受各种的实参,并根据他们来决定如何解读日期
--snip--
# 从文件中获取日期、最高温度和最低温度
dates, highs, lows = [], [], []
# 通过通过模块和方法我们能解读文件中的日期
# '%Y-' 将第一个连字符前面的部分视为四位的年份
# '%m-' 将第二个连字符前面的部分视为月份的数
# '%d-' 将字符串最后一部分视为月份中的一天
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)
ax.plot(dates, highs, c='red', alpha=0.5) # dates就表示X轴数据
--snip--
将使用方法 fill_between() 来填充两个y值之间的空间,使得图表中的数据更加的可视化
--snip--
# 根据最高温度和最低温度绘制图形
plt.style.use('seaborn')
fig, ax = plt.subplots()
# alpha指定颜色的透明度
ax.plot(dates, highs, c='red', alpha=0.5)
ax.plot(dates, lows, c='blue', alpha=0.5)
# facecolor填充颜色
ax.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
--snip--
由于缺失数据可能引发异常,如果不妥善处理,可能导致程序崩溃
--snip--
# 从文件中获取最高的温度
highs = []
for row in reader:
high = int(row[5])
highs.append(high)
print(highs)
--snip--
在运行以上程序时出现了错误,如下述输出的最后一行所示:
Traceback (most recent call last):
File "csv_file_t.py", line 15, in <module>
high = int(row[5])
ValueError: invalid literal for int() with base 10: ''
该 Traceback 指出,Python无法处理其中一天的 最高温度,因为无法将空字符(’ ')转换为整数
为此,在从CSV文件中读取值时执行错误检查代码,对可能出现的异常进行处理,如下所示:
--snip--
dates, highs, lows = [], [], []
for row in reader:
current_date = datetime.strptime(row[2], '%Y/%m/%d')
try:
high = int(row[5])
low = int(row[6])
except ValueError:
print(f"Missing data for {current_date}")
else:
dates.append(current_date)
highs.append(high)
lows.append(low)
--snip--
只要缺失其中一项数据,Python就会引发 ValueError 异常。我们这样进行处理:打印一条错误信息,指出缺失数据的日期。之后循环将接着处理下一行数据。
缺失数据输出如下:
Missing data for 2018-01-01 00:00:00
本节主要实现的功能是:制作全球地震散点图
函数 json.load() 将数据转化为Python能够处理的格式,是一个庞大的字典文件,随后我们创建一个新的文件将数据存入其中。
函数 json.dump() 接受一个JSON数据对象和一个文件对象,并将数据写入这个文件中。参数 indent=4 让 dump() 使用与数据结构匹配的缩进量来设置数据的格式。
import json
# 我理解的思路是:先转换格式,再存入新的文件
# 探索数据的结构
filename = 'eq_data_1_day_m1.json'
with open(filename) as f:
all_eq_data = json.load(f)
# 创建一个新的空json文件
readable_file = 'readable_eq_data.json'
# 打开刚才新创建的文件,写入模式
with open(readable_file, 'w') as f:
json.dump(all_eq_data, f, indent=4)
文件 readable_eq_data.json 数据如下图显示:
这个文件的数据看不明白(字典嵌套列表 / 列表嵌套字典)
据上一小节描述以及图片,我们得知 JSON数据 是一个庞大的 字典文件 。现在,我们创建一个列表存储所有地震的各种信息,并提取其中的震级。
其中疑惑的是:all_eq_dicts = all_eq_data[‘features’]
为什么 all_eq_dicts 是一个列表?
import json
filename = 'eq_data_1_day_m1.json'
with open(filename) as f:
all_eq_data = json.load(f)
# 提取与键 'features' 相关联的数据
all_eq_dicts = all_eq_data['features']
print(len(all_eq_dicts)) #
# 提取:震级, 存储位置的标题, 经度, 纬度
mags, titles, lons, lats = [], [], [], []
#遍历列表
for eq_dict in all_eq_dicts:
# 字典'properties'中的'mag'键的值就是震级
# 字典'geomrtey'中的'coordinates'键的第一、二个值就是经纬度
mag = eq_dict['properties']['mag']
title = eq_dict['properties']['title']
lon = eq_dict['geometry']['coordinates'][0]
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])
输出结果:文件数据都提取正常,接下来就是进行数据可视化
输出结果:
158 # 表明这个文件记录了158次地震
[0.96, 1.2, 4.3, 3.6, 2.1, 4, 1.06, 2.3, 4.9, 1.8]
['M 1.0 - 8km NE of Aguanga, CA', 'M 1.2 - 11km NNE of North Nenana, Alaska']
[-116.7941667, -148.9865, -74.2343, -161.6801, -118.5316667]
[33.4863333, 64.6673, -12.1025, 54.2232, 35.3098333]
首先要实现一个简单的震级散点图,之后随着代码不断的完善再补充内容
在这里 Plotly 制图就不再赘述,语法与 Matplotlib 类似
这里所用的是 Plotly Express 来定义图表数据
import plotly.express as px
fig = px.scatter(
x=lons,
y=lats,
labels={'x': '经度', 'y': '纬度'},
range_x=[-200,200], # x,y轴的取值范围
range_y=[-200,200],
width=800, # 散点图显示的高度,宽度设置为800像素
height=800,
title='全球地震散点图'
)
# fig.write_html 方法将可视化图保存为html文件
fig.write_html('global_earthquakes.html')
fig.show()
global_earthquakes.html 图片如下:
我们可以看出现在的可视化图提供给我们的数据还是很有限的,所以接下来我们将继续完善
接下来,我们来看看两个的区别:
一、 Plotly Express 来定义图表数据,当前的经纬度数据是手动配置的
--snip--
x=lons,
y=lats,
labels={'x': '经度', 'y': '纬度'},
--snip--
二、pandas 定义图表数据
在这种方式中,所有有关数据的信息都以键值对的形式放在一个字典中。
import pandas as pd
data = pd.DataFrame(
data=zip(lons, lats, titles, mags), columns=
['经度', '纬度', '位置', '震级']
)
data.head()
上文我们只是简单的在散点图显示在哪发生了地震,但没有指出震级,接下来就是要实现这个,定制标记的颜色让可视化图变得生动
--snip--
fig = px.scatter(
data,
x='经度',
y='纬度',
range_x=[-200,200],
range_y=[-200,200],
width=800,
height=800,
title='全球地震散点图',
# 新加入的大小以及颜色
size='震级',
size_max=10, # 标记尺寸默认是20像素
color='震级' #默认的视觉映射图例渐变色是从小-蓝-红-黄-大
--snip--
)
可视化图如下:有了颜色渐变,以及标记点的大小区别,这样的可视化图能将关键信息显示的一目了然
在之前我们用 pandas 配置了 titles:'位置 '
接下来,我们用一句简单的代码实现这个功能
-snip--
hover_name='位置'
--snip--