前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Pandas地震数据获取与可视化

Pandas地震数据获取与可视化

作者头像
用户2183996
修改2019-09-22 17:39:54
1.1K0
修改2019-09-22 17:39:54
举报
文章被收录于专栏:技术沉淀技术沉淀

开公众号啦,分享读书心得,欢迎一起交流成长。

资源

代码语言:javascript
复制
import pandas as pd
import requests
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
%matplotlib inline

小练习

参见此处

代码语言:javascript
复制
html_1 = requests.get('http://zh.wikipedia.org/wiki/%E7%9C%81%E4%BC%9A')
html_1_text = html_1.text
dfs_1 = pd.read_html(html_1_text,header=0,attrs={'class': 'wikitable'})
dfs_1[0].head()

編號

行政區

簡稱

省會或首府

地區

Unnamed: 5

編號.1

行政區.1

簡稱.1

省會或首府.1

地區.1

0

1

江蘇省

鎮江

華中

20

甘肅省

蘭州

華北

NaN

1

2

浙江省

杭州

華中

21

寧夏省

銀川

塞北

NaN

2

3

安徽省

合肥

華中

22

青海省

西寧

西部

NaN

3

4

江西省

南昌

華中

23

綏遠省

歸綏(今呼和浩特)

塞北

NaN

4

5

湖北省

武昌(今武漢)

華中

24

察哈爾省

張垣(今張家口)

塞北

NaN

读取表格read_html

安装

read_html依赖一些库,比如html5lib,lxml,beautiful soup等,如果没有安装会报错。

Bug

直接用pd.read_html()一直出错,上个小例子没问题,但读取这个网站出了问题: AttributeError: 'NoneType' object has no attribute 'next_element' google后发现可能是beautifulsoup4版本的问题,在这找到一点线索,然后pip uninstall beautifulsoup4 and pip install beautifulsoup4=='4.0.5'解决问题了,不是很清楚为何。

吐槽

本来就想安安静静地写一行解决问题,谁知道还有坑有坑 dsf = pd.read_html('http://data.earthquake.cn/datashare/globeEarthquake_csn.html',header=0)[4] 执行后文字部分都是乱码,应该是编码问题,下面给出了解决方案。

不过我忍不住要吐槽一句,为什么这个网站把所以的内容都放在table里,如果这样,能不能给个id或者class,导致利用attrs精确获得表格的微操失败,心中也是万马奔腾。

获取数据

代码语言:javascript
复制
url = 'http://data.earthquake.cn/datashare/globeEarthquake_csn.html'
html = requests.get(url)

乱码问题

request默认是ISO-8859-1编码,这里会导致乱码

代码语言:javascript
复制
html.encoding
代码语言:javascript
复制
'ISO-8859-1'
代码语言:javascript
复制
html_text = html.text
dfs = pd.read_html(html_text,header=0)
dfs[4].head()

·¢ÕðÈÕÆÚ

·¢Õðʱ¿Ì

γ¶È(¡ã)

¾­¶È(¡ã)

Éî¶È(km)

Õð¼¶

ʼþÀàÐÍ

²Î¿¼µØµã

0

2016-05-24

20:12:09.6

40.9

79.3

6

Ms3.2

ÌìÈ»µØÕð

н®°¢¿ËËÕµØÇøÎÚʲÏØ

1

2016-05-24

18:34:34.2

40.2

77.2

8

Ms3.0

ÌìÈ»µØÕð

н®¿Ë×ÎÀÕËÕÖÝ°¢Í¼Ê²ÊÐ

2

2016-05-24

08:56:14.7

37.4

92.9

10

Ms3.0

ÌìÈ»µØÕð

Çຣº£Î÷Öݸñ¶ûľÊÐ

3

2016-05-24

03:09:56.5

28.0

85.3

8

Ms3.8

ÌìÈ»µØÕð

Äá²´¶û

4

2016-05-24

02:09:01.5

28.6

87.5

7

Ms3.9

ÌìÈ»µØÕð

Î÷²ØÈÕ¿¦ÔòÊж¨ÈÕÏØ

改变默认编码

代码语言:javascript
复制
html.encoding =  html.apparent_encoding
html.encoding #竟然是GB2312,一开始窃以为是UTF-8...
代码语言:javascript
复制
'GB2312'
代码语言:javascript
复制
html_text = html.text
dfs = pd.read_html(html_text,header=0) # 返回的是一个list,list里是表格
dfs[4].head()

发震日期

发震时刻

纬度(°)

经度(°)

深度(km)

震级

事件类型

参考地点

0

2016-05-24

20:12:09.6

40.9

79.3

6

Ms3.2

天然地震

新疆阿克苏地区乌什县

1

2016-05-24

18:34:34.2

40.2

77.2

8

Ms3.0

天然地震

新疆克孜勒苏州阿图什市

2

2016-05-24

08:56:14.7

37.4

92.9

10

Ms3.0

天然地震

青海海西州格尔木市

3

2016-05-24

03:09:56.5

28.0

85.3

8

Ms3.8

天然地震

尼泊尔

4

2016-05-24

02:09:01.5

28.6

87.5

7

Ms3.9

天然地震

西藏日喀则市定日县

代码语言:javascript
复制
df = dfs[4] 
df.columns = ['date','time','lats','lons','dept','mag','class','place']
代码语言:javascript
复制
df.head(3)

date

time

lats

lons

dept

mag

class

place

0

2016-05-24

20:12:09.6

40.9

79.3

6

Ms3.2

天然地震

新疆阿克苏地区乌什县

1

2016-05-24

18:34:34.2

40.2

77.2

8

Ms3.0

天然地震

新疆克孜勒苏州阿图什市

2

2016-05-24

08:56:14.7

37.4

92.9

10

Ms3.0

天然地震

青海海西州格尔木市

画地震分布图

不太懂地震,除了了解一下分布,不知道还分析什么,就先画个分布图吧。

把以Ms震级开头的行去掉(共7个),只保留ML开头的,便于分析

代码语言:javascript
复制
Ms = df.mag.map(lambda x: not x.startswith('Ms')) # boolean Series
df = df[Ms]

把震级转换为数字

代码语言:javascript
复制
import re
get_num = lambda x: float(re.findall('\d+\.\d+', x)[0])
# a = 'ML0.5'
# n = re.findall('\d+\.\d+', a)
# float(n[0])
# df['mag_num'].loc[:] = df.loc[:,'mag'].map(get_num)
# df['mag_num'] = df['mag'].map(get_num) 会报错
# http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
temp =  df['mag'].map(get_num)
df.loc[:,('mag_num')] = temp
df.head(3)

date

time

lats

lons

dept

mag

class

place

mag_num

5

2016-05-23

23:43:52.5

23.30

103.21

6

ML1.7

天然地震

云南个旧

1.7

6

2016-05-23

23:43:33.9

39.82

118.76

8

ML0.5

天然地震

河北滦县

0.5

7

2016-05-23

23:36:25.9

39.60

76.93

6

ML1.4

天然地震

新疆伽师

1.4

获取地图分布范围,经纬度表示
代码语言:javascript
复制
# lower left
llcrnrlon, llcrnrlat = df['lons'].min(), df['lats'].min()
# upper right
urcrnrlon, urcrnrlat = df['lons'].max(), df['lats'].max()
获取地震地点经纬度及强度
代码语言:javascript
复制
lons, lats = list(df['lons']), list(df['lats'])
mags = list(df['mag_num'])
辅助函数

不同的等级用不同的颜色

代码语言:javascript
复制
# 按等级配色
def get_marker_color(magnitude):
    # Returns green for small earthquakes, yellow for moderate
    #  earthquakes, and red for significant earthquakes.
    if magnitude < 1.5:
        return ('go')
    elif magnitude < 3.0:
        return ('yo')
    else:
        return ('ro')
作图
代码语言:javascript
复制
fig = plt.figure(figsize=(14,10))
ax = plt.subplot(1,1,1)
eq_map = Basemap(projection='merc', resolution = 'l', area_thresh = 1000.0,
              lat_0=0, lon_0=120,
              llcrnrlon=llcrnrlon-5, llcrnrlat=llcrnrlat-8,
              urcrnrlon=urcrnrlon+10, urcrnrlat=urcrnrlat+3)

eq_map.drawcoastlines()
eq_map.drawcountries()
eq_map.fillcontinents(color = 'lightgray')
eq_map.drawmapboundary()
eq_map.drawmeridians(np.arange(0, 360, 30))
eq_map.drawparallels(np.arange(-90, 90, 30))

min_marker_size = 4
for lon, lat, mag in zip(lons,lats,mags):
    x,y = eq_map(lon, lat)
    msize = mag*min_marker_size
    marker_string = get_marker_color(mag)
    eq_map.plot(x, y, marker_string, markersize=msize)

plt.show()
地震分布
地震分布

地震分布

可以看到最近一段时间地震在全国范围内的分布。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.07.03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 资源
  • 小练习
  • 读取表格read_html
    • 安装
      • Bug
        • 吐槽
        • 获取数据
          • 乱码问题
            • 改变默认编码
            • 画地震分布图
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档