本案例针对全球重大地震数据进行分析,采用Python为编程语言,采用Hadoop存储数据,采用Spark对数据进行处理分析,并对结果进行数据可视化。
此外,还需要安装plotly用于绘制地图,安装wordcloud用于绘制词云图。
本博客中的Python代码均运行在JupyterNotebook上。
在用户目录下创建一个NoteBook文件夹,将earthquake.csv文件放入NoteBook中,接着打开JupyterNotebook。
在代码框中输入代码,运行后可以直接显示结果。首先从文件中读取数据:
Pandas提供了to_datetime()方法,可以将不同的日期格式转换为datetime类型。设置errors='coerce'参数,遇到不能转换的格式时将其置为NaN。
rawData.loc[3378,'StructedDate']='1975-02-23'rawData.loc[7512,'StructedDate']='1985-04-28'rawData.loc[20650,'StructedDate']='2011-03-13'delrawData['Date']接着按照同样地步骤对Time数据进行清洗。
经过测试,这个API对于中国境外的坐标不能准确地返回结果,因此只获取在中国境内的坐标信息。坐标在中国境外时,就返回一个空值。如果坐标在海上,就获取海域的名称(如南海);如果在陆地上,就获取省份的名称。
编写程序为每个坐标获取地名信息,并将其存到Area列中。这个过程大概需要花费10分钟。
查看Type数据中是否存在异常值。
至此,数据清洗工作完成,将数据保存到earthquake_cleaned.csv文件中。使用utf-8编码防止Spark读取时出现中文乱码,设置index=False防止将第一列索引保存至文件中。
rawData.to_csv("earthquake_cleaned.csv",encoding='utf-8',index=False)上传到HDFS以便Spark进行数据分析。
首先要对Date属性进行拆分,分别得到年月日的信息。
将Date属性拆分后发现年月日信息都是字符串类型,将其改为整型。
forxinattrsName:df=df.withColumn(x,df[x].cast('int'))接下来对数据分别按年月日计数并将结果保存到文件中,方便之后进行可视化。由于使用Spark自带的函数将DataFrame保存为csv文件时,文件会保存为文件夹,在本地读取时比较麻烦。因此使用toPandas()方法将Spark的DataFrame转换成pandas的DataFrame,再保存为csv文件,方便可视化时读取。
countByYear=df.groupBy("Year").count().orderBy("Year")countByYear.toPandas().to_csv("countByYear.csv",encoding='utf-8',index=False)countByMonth=df.groupBy("Month").count().orderBy("Month")countByMonth.toPandas().to_csv("countByMonth.csv",encoding='utf-8',index=False)countByDay=df.groupBy("Day").count().orderBy("Day")countByDay.toPandas().to_csv("countByDay.csv",encoding='utf-8',index=False)2.中国境内每个省份(海域)发生重大地震的次数首先筛选出中国境内发生的重大地震信息,保存到文件中。
earthquakeC=df.filter("Areaisnotnull")earthquakeC.toPandas().to_csv("earthquakeC.csv",encoding='utf-8',index=False)按Area属性对数据进行分组计数,要注意只统计Area非空的数据。
countByArea=earthquakeC.groupBy("Area").count()countByArea.toPandas().to_csv("countByArea.csv",encoding='utf-8',index=False)3.不同类型地震的数量分别计算出中国境内和世界范围内的不同地震类型的数量。
mostPow=df.sort(df["Magnitude"].desc(),df["Year"].desc()).take(500)mostPowDF=spark.createDataFrame(mostPow)mostPowDF.toPandas().to_csv("mostPow.csv",encoding='utf-8',index=False)5.震源深度前500的地震当震源深度相同时,将震级更高的地震排在前面。
mostDeep=df.sort(df["Depth"].desc(),df["Magnitude"].desc()).take(500)mostDeepDF=spark.createDataFrame(mostDeep)mostDeepDF.toPandas().to_csv("mostDeep.csv",encoding='utf-8',index=False)6.震级与震源深度的关系将数据中的Depth和Magnitude拿出来,保存到文件中。
df.select(df["Magnitude"],df["Depth"]).toPandas().to_csv("powDeep.csv",encoding='utf-8',index=False)至此数据分析基本完成,将df也保存到csv文件中,用于数据可视化。
df.toPandas().to_csv("earthquake1.csv",encoding='utf-8',index=False)四、数据可视化可视化工具使用plotly,可以绘制可交互的图表,支持保存为html格式的文件方便查看,并可以完美兼容JupyterNotebook。另外,用WordCloud绘制词云。
首先将所有数据绘制到地图上。根据我们的常识,地震震级越高,地震的破坏力呈几何级数上升。为了画出更直观的图,使用exp(Magnitude)/100作为每个坐标的大小。画出的图都保存为html格式,方便查看。
根据数据分析结果画出柱状图。
前十多年的地震次数明显少于之后的,可能是早期地震监测技术比较落后的原因。