数据分析实例 -- 气象数据
【惠人榨汁机**维修】 本课程难度为中等,适合具有Python基础的用户,如果对 matplotlib 模块有了解会更快的上手。 你可以通过下面命令将代码下载到实验楼环境中,作为参照对比进行学习。 本实验在交互式的环境当中完成,代码不能直接在命令行中运行(因为要画图)。如果想要看效果的同学可以把和?解压,然后打开桌面上的 spyder, 在Ipython console的交互式环境中进入所在路径,然后把代码黏贴到 console 当中去。具体方式请看如下的 gif 图。
在这里还是要呼吁大家不要简单的复制粘贴代码,还是要依照本实验的教程自己一步步得实现。 气象数据是在网上很容易找到的一类数据。很多网站都提供以往的气压、气温、湿度和降雨量等气象数据。只需指定位置和日期,就能获取一个气象数据文件。这些测量数据是由气象站收集的。气象数据这类数据源涵盖的信息范围较广。数据分析的目的是把原始数据转化为信息,再把信息转化为知识,因此拿气象数据作为数据分析的对象来讲解数据分析全过程再合适不过。 写作本章时,虽正值夏初,却已酷热难耐,住在大城市的人感受更为强烈。于是周末很多人到山村或海滨城市去游玩,放松一下身心,远离内陆城市的闷热天气。我常常想,靠海对气候有什么影响?这个问题可以作为数据分析的一个不错的出发点。我不想把本章写成科学类读物,只是想借助这样一种方式,让数据分析爱好者能够把所学用于实践,解决“海洋对一个地区的气候有何影响”这个问题。 研究系统:亚得里亚海和波河流域 既然已定义好问题,就需要寻找适合研究数据的系统,提供适合回答这个问题的环境。首先,需要找到一片海域供你研究。我住在意大利,可选择的海有很多,因为意大利是一个被海洋包围的半岛国家。为什么要把自己的选择局限在意大利呢?因为我们所研究的问题刚好和意大利人的一种典行为相关,也就是夏天我们喜欢躲在海边,以躲避内陆的酷热。我不知道在其他国家这种行为是否也很普遍,因此我只把自己熟悉的意大利作为一个系统进行研究。但是你可能会考虑研究意大利的哪个地区呢?上面说过,意大利是半岛国家,找到可研究的海域不是问题,但是如何衡量海洋对其远近不同的地方的影响?这就引出了一个大问题。意大利其实多山地,离海差不多远,可以彼此作为参照的内陆区域较少。为了衡量海洋对气候的影响,我排除了山地,因为山地也许会引入其他很多因素,比如海拔。 意大利波河流域这块区域就很适合研究海洋对气候的影响。这一片平原东起亚得里亚海,向内陆延伸数百公里(见图9-1)。它周边虽不乏群山环绕,但由于它很宽广,削弱了群山的影响。此外,该区域城镇密集,也便于选取一组离海远近不同的城市。我们所选的几个城市,两个城市间的**距离约为400公里。 **步,选10个城市作为参照组。选择城市时,注意它们要能代表整个平原地区(见图9-2)。 如图9-2所示,我们选取了10个城市。随后将分析它们的天气数据,其中5个城市在距海100公里范围内,其余5个距海100~400公里。 选作样本的城市列表如下:
现在,我们需要弄清楚这些城市离海有多远。方法有多种。这里使用TheTimeNow网站提供的服务,它支持多种语言(见图9-3)。 有了计算两城市间距离这样的服务,我们就可以计算每个城市与海之间的距离。你可以选择 海滨城市Comacchio作为基点,计算其他城市与它之间的距离(见图9-2)。使用上述服务计算完 所有距离后,得到的结果如表9-1所示。 定义好要研究的系统之后,我们就需要创建数据源,以获取研究所需的数据。上网浏览一番,你就会发现很多网站都提供世界各地的气象数据,其中就有Open Weather Map,它的网址是?http://openweathermap.org/?(见图9-4)。 该网站提供以下功能:在请求的URL中指定城市,即可获取该城市的气象数据。我们已经准备好了数据,不需要大家再去调用该网站的 API。 启动桌面上的spyder。如果您发现您桌面上没有spyder,请在该实验中重新开一个实验环境(实验楼为不同的实验创建不同的实验环境): 我们首先来获取我们的数据文件。打开 Xfce 终端 这时候应该能够再 WeatherData 中间看到 10 个城市的天气数据文件(以 .csv 结尾) 双击打开 spyder ,在 Ipython Console 中进入我们的目标目录 我们在实验里只需要用到 Ipython Console 所以别的不相关的窗口可以关闭。 如果你想用本章的数据,需要加载写作本章时保存的10个CSV文件。 我们把这些数据读入内存,完成了实验准备的部分。 ?代表的是每一张分析图所使用的代码。 ?是我们的数据。 从数据可视化入手分析收集到的数据是常见的做法。前面讲过,matplotlib库提供一系列图表生成工具,能够以可视化形式表示数据。数据可视化在数据分析阶段非常有助于发现研究系统的一些特点。 导入以下必要的库: 举例来说,非常简单的分析方法是先分析一天中气温的变化趋势。我们以城市米兰为例。 执行上述代码,将得到如图9-8所示的图像。由图可见,气温走势接近正弦曲线,从早上开始气温逐渐升高,最高温出现在下午两点到六点之间,随后气温逐渐下降,在第二天早上六点时达到最低值。
我们进行数据分析的目的是尝试解释是否能够评估海洋是怎样影响气温的,以及是否能够影响气温趋势,因此我们同时来看几个不同城市的气温趋势。这是检验分析方向是否正确的**方式。因此,我们选择三个离海最近以及三个离海最远的城市。 上述代码将生成如图9-9所示的图表。离海最近的三个城市的气温曲线使用红色,而离海最远的三个城市的曲线使用绿色。
如图9-9所示,结果看起来不错。离海最近的三个城市的最高气温比离海最远的三个城市低不少,而最低气温看起来差别较小。 我们可以沿着这个方向做深入研究,收集10个城市的最高温和最低温,用线性图表示气温最值点和离海远近之间的关系。 先把最高温画出来。 结果如图9-10所示。
如图9-10所示,现在你可以证实,海洋对气象数据具有一定程度的影响这个假设是正确的(至 少这一天如此)。 进一步观察上图,你会发现海洋的影响衰减得很快,离海60~70公里开外,气温就已攀升到 高位。 用线性回归算法得到两条直线,分别表示两种不同的气温趋势,这样做很有趣。我们可以使 用scikit-learn库的SVR方法。(注意:这段代码会跑比较久的时间) 这里会返回 [10, 20, 30,..., 90],如果把列表看成是一个矩阵,那么这个矩阵是 1?9 的。这里函数就会把该列表变为 1?9 的, [[10], [20], ..., [90]]。这么做的原因是因为函数的只能接受一个 N?1 的列表,返回一个 1?N 的列表。 上述代码将生成如图9-11所示的图像。
如上所见,离海60公里以内,气温上升速度很快,从28度陡升至31度,随后增速渐趋缓和(如果还继续增长的话),更长的距离才会有小幅上升。这两种趋势可分别用两条直线来表示,直线的表达式为: 其中a为斜率,b为截距。 你可能会考虑将这两条直线的交点作为受海洋影响和不受海洋影响的区域的分界点,或者至少是海洋影响较弱的分界点。 执行上述代码,将得到交点的坐标 [x,y] = [ 53, 30 ] 并得到如图9-12所示的图表。
因此,你可以说海洋对气温产生影响的平均距离(该天的情况)为53公里。 现在,我们可以转而分析最低气温。
在这个例子中,很明显夜间或早上6点左右的最低温与海洋无关。如果没记错的话,小时候老师教给大家的是海洋能够缓和低温,或者说夜间海洋释放白天吸收的热量。但是从我们得到情况来看并非如此。我们刚使用的是意大利夏天的气温数据,而验证该假设在冬天或其他地方是否也成立,将会非常有趣。 10个DataFrame对象中还包含湿度这个气象数据。因此,你也可以考察当天三个近海城市和 三个内陆城市的湿度趋势。 上述代码将生成如图9-14所示的图表。
乍看上去好像近海城市的湿度要大于内陆城市,全天湿度差距在20%左右。我们再来看一下湿度的极值和离海远近之间的关系,是否跟我们的**印象相符。 我们把10个城市的**湿度与离海远近之间的关系做成图表,请见图9-15。
再来把10个城市的最小湿度与离海远近之间的关系做成图表,请见图9-16。
由图9-15和图9-16可以确定,近海城市无论是**还是最小湿度都要高于内陆城市。然而在 我看来,我们还不能说湿度和距离之间存在线性关系或者其他能用曲线表示的关系。我们采集的 数据点数量(10)太少,不足以描述这类趋势。 在我们采集的每个城市的气象数据中,下面两个与风有关:
分析存放每个城市气象数据的DataFrame就会发现,风速不仅跟一天的时间段相关联,还与 一个介于0~360度的方向有关。例如,每一条测量数据也包含风吹来的方向(图9-17)。
为了更好地分析这类数据,有必要将其做成可视化形式,但是对于风力数据,将其制作成使用笛卡儿坐标系的线性图不再是**选择。 要是把一个DataFrame中的数据点做成散点图 就会得到图9-18这样的图表,很显然该图的表现力也有不足。
要表示呈360度分布的数据点,**使用另一种可视化方法:极区图。 首先,创建一个直方图,也就是将360度分为八个面元,每个面元为45度,把所有的数据点分到这八个面元中。 histogram()函数返回结果中的数组hist为落在每个面元的数据点数量。 [ 0 5 11 1 0 1 0 0] 返回结果中的数组bins定义了360度范围内各面元的边界。 [ 0. 45. 90. 135. 180. 225. 270. 315. 360.] 要想正确定义极区图,离不开这两个数组。我们将创建一个函数来绘制极区图,其中部分代码在第7章已讲过。我们把这个函数定义为showRoseWind(),它有三个参数:values数组,指的是想为其作图的数据,也就是这里的hist数组;第二个参数city_name为字符串类型,指定图表标题所用的城市名称;最后一个参数max_value为整型,指定**的蓝色值。 定义这样一个函数很有用,它既能避免多次重复编写相同的代码,还能增强代码的模块化程度,便于你把精力放到与函数内部操作相关的概念上。 你需要修改变量colors存储的颜色表。这里,扇形的颜色越接近蓝色,值越大。定义好函数之后,调用它即可: 运行上述函数,将得到如图9-19所示的极区图。
由图9-19可见,整个360度的范围被分成八个区域(面元),每个区域弧长为45度,此外每个区域还有一列呈放射状排列的刻度值。在每个区域中,用半径长度可以改变的扇形表示一个数值,半径越长,扇形所表示的数值就越大。为了增强图表的可读性,我们使用与扇形半径相对应的颜色表。半径越长,扇形跨度越大,颜色越接近于深蓝色。 从刚得到的极区图可以得知风向在极坐标系中的分布方式。该图表示这一天大部分时间风都 吹向西南和正西方向。 定义好showRoseWind()函数之后,查看其他城市的风向情况也非常简单。
即使是跟风速相关的其他数据,也可以用极区图来表示。 定义RoseWind_Speed函数,计算将360度范围划分成的八个面元中每个面元的平均风速。 这里获取的是风向大于 'deg-46' 度和风向小于 'deg' 的数据。 RoseWind_Speed() 函数返回一个包含八个平均风速值的NumPy数组。该数组将作为先前定义的showRoseWind()函数的**个参数,这个函数是用来绘制极区图的。 图9-21所示的风向频率玫瑰图表示风速在360度范围内的分布情况。
本章主要目的是演示如何从原始数据获取信息。其中有些信息无法给出重要结论,而有些信息能够验证假设,增加我们对系统状态的认识,而找出这种信息也就意味着数据分析取得了成功。 如果学完本课程,对书籍其他内容感兴趣欢迎点击以下链接购买书籍:
文章分类:
最新资讯
|