全球近10年灾害数据分析与可视化:揭示灾害趋势与风险预测

爬取全球地质灾害信息(附网站+源码)


一、简介

灾害是世界面临的共同挑战,为了更好地了解全球灾害的分布和趋势,我开发了一个基于 Python 的爬虫程序,从某网站上获取了近10年的全球灾害数据。通过数据分析和可视化,我揭示了不同洲际和国家的灾害分布,对灾害类型进行了分类,并通过模型训练预测了灾害的风险。在本博客中,我将与大家分享我整个研究的过程和结果。

二、相关流程

  1. 通过分析网站数据,可以发现数据存放在json中,通过观察相应的数据,找到相对于的请求页面。

在这里插入图片描述

  1. 获取到请求网站,通过观察可以发现可以通过改变蓝框中的数值,达到改变页面展示条数、当前显示第几页、显示多长时间的数据(注:通过天数来改变)。

在这里插入图片描述

三、过程分析

  1. 数据爬取

    使用 Python 的 requests 库从指定网站上爬取了全球近10年的灾害数据,并将数据存储为 DataFrame 格式。对于重复数据和缺失值,采用了去重和填充的方法,保证了数据的准确性和完整性。

# https://www.gddat.cn/ssjc/disaster/getDisasterList?pageNo=2&pageSize=20&eventtype=&countryname=&frequency=365&orderby=affected&tableName=emdat&fromdate=&todate=

import requests
import json
import jsonpath

import pandas as pd

pd.set_option('display.max_columns', None)  # 显示完整的列
pd.set_option('display.max_rows', None)  # 显示完整的行
pd.set_option('display.expand_frame_repr', False)

df = pd.DataFrame()

for i in range(1, 136):
      url = 'https://www.gddat.cn/ssjc/disaster/getDisasterList?pageNo=' + str(
            i) + '&pageSize=20&eventtype=&countryname=&frequency=3650' \
                 '&orderby=affected&tableName=emdat&fromdate=&todate='

      response = requests.get(url)
      response.encoding = 'utf-8'
      content = response.text

      data = json.loads(content)
      data_list = jsonpath.jsonpath(data, '$..list.*')

      list1 = []
      # 从data_list中根据键名取出需要的值
      for key, value in enumerate(data_list):
            my_list = list(value.values())
            continent = value.get('continent')
            country = value.get('country')
            code_two = value.get('code_two')
            enentparent = str(value.get('enentparent'))
            todate = value.get('todate')
            fromdate = value.get('fromdate')
            list1.append([continent, country, code_two, enentparent, todate, fromdate])
      print(list1)

      df = df._append(pd.DataFrame(list1))
df.to_csv('自然灾害.csv', index=False, header=True, encoding='utf-8')
  1. 数据分许及预处理

通过对数据进行处理和清洗,得到了洲名、国家、国家简称、灾害类型、结束时间和开始时间六列数据。对于重复数据和缺失值,采用了去重和填充的方法,保证了数据的准确性和完整性。

import pandas as pd
df = pd.read_csv(r'D:\BigData\pythonProject\爬虫\requests\自然灾害.csv')

# 重命名列名
df.columns = ['洲名', '国家', '国家简称', '灾害类型', '结束时间', '开始时间']
# 提取国家简称,供后续使用
df_abbr = df[['国家简称', '结束时间']]

# 对国家列进行处理
df['国家'] = df['国家'].str.split(',') # 根据逗号进行分隔
# df['国家简称'] = df['国家简称'].str.split(',')
# 把分隔开的数据展开成新的行
df = df.explode('国家',ignore_index=True)

# 对国家简称列进行拆分,同上
df_abbr['国家简称'] = df_abbr['国家简称'].str.split(',')
df_abbr = df_abbr.explode('国家简称', ignore_index=True)
df['国家简称'] = df_abbr['国家简称']

# 处理缺失值
df.isnull().sum()
df = df.dropna() # 删除为空的洲
df.reset_index(drop=True, inplace=True)
  1. 灾害类型分类与分布

在灾害类型方面,我使用了ID来进行分类替换,以更直观地展示不同类型的灾害在全球的分布情况。

# 对灾害类型进行说明
# 1-地震、3-火山、4-洪涝、5-干旱、6-风暴、7-其他气象灾害、9-野火
for i in range(0, len(df)):
    data = df['灾害类型'][i]
    if data == 1:
        df['灾害类型'][i] = '地震'
    elif data == 3:
        df['灾害类型'][i] = '火山'
    elif data == 4:
        df['灾害类型'][i] = '洪涝'
    elif data == 5:
        df['灾害类型'][i] = '干旱'
    elif data == 6:
        df['灾害类型'][i] = '风暴'
    elif data == 7:
        df['灾害类型'][i] = '其他自然灾害'
    elif data == 9:
        df['灾害类型'][i] = '野火'
    elif data == 2:
        df['灾害类型'][i] = '地质灾害'
df
  1. 数据可视化

在数据可视化方面,利用 Matplotlib 和 Seaborn 等工具,对灾害类型进行了饼状图的绘制,展示了各类型灾害在全球范围内的占比情况。同时,通过堆叠图展示了洲名和灾害类型之间的关系,从而帮助读者更好地理解灾害的分布和趋势。

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = 'SimHei'    #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False    #用来显示负号

disaster = df['灾害类型'].value_counts() # 统计灾害的样本数量
plt.pie(disaster, labels=['地震', '火山', '洪涝', '干旱', '风暴', '其他自然灾害', '野火', '地质灾害'], autopct='%.1f%%')
plt.show()

在这里插入图片描述

# 使用pivot_table方法进行分组和聚合
grouped_df = df.pivot_table(index=['洲名', '灾害类型'], aggfunc='size').unstack(fill_value=0)

# 绘制堆叠条形图
grouped_df.plot(kind='bar', stacked=True, figsize=(10, 6))
plt.xlabel('洲名')
plt.ylabel('统计次数')
plt.title('国家和灾害类型分布')
plt.legend(title='灾害类型')
plt.xticks(rotation=0)
plt.show()

在这里插入图片描述

  1. 灾害风险预测

使用了机器学习的模型进行了灾害风险的预测。通过对历史数据的学习,建立一个预测模型,并通过准确率预测了未来可能发生的灾害风险,为防灾减灾工作提供了重要参考。

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 假设您的数据存储在一个名为df的DataFrame中
# df = pd.read_csv('your_data.csv')  # 从CSV文件中读取数据

# 进行数据预处理,将文本数据转换为数值型数据
label_encoder = LabelEncoder()
df['洲名'] = label_encoder.fit_transform(df['洲名'])
df['国家'] = label_encoder.fit_transform(df['国家'])
df['国家简称'] = label_encoder.fit_transform(df['国家简称'])
df['灾害类型'] = label_encoder.fit_transform(df['灾害类型'])

# 特征选择,假设我们只选取'洲名', '国家', '国家简称', '结束时间', '开始时间'作为特征
features = df[['洲名', '国家', '国家简称']]
target = df['灾害类型']

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.2, random_state=42)

# 建立随机森林分类器模型
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)

# 模型训练
rf_classifier.fit(X_train, y_train)

# 模型预测
y_pred = rf_classifier.predict(X_test)

# 计算模型准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率:{accuracy}")

在这里插入图片描述

四、结论与展望

在本研究中,我通过爬取全球灾害数据、进行数据分析和可视化、使用机器学习模型进行风险预测,揭示了全球灾害的分布和趋势,为灾害防范和减灾提供了重要信息。然而,由于数据的局限性和模型的简化,本研究仍有待进一步完善。未来,我将继续深入研究灾害数据,探索更多有效的灾害预防措施,为人类社会的安全和稳定做出更大的贡献。

五、完整代码

# https://www.gddat.cn/ssjc/disaster/getDisasterList?pageNo=2&pageSize=20&eventtype=&countryname=&frequency=365&orderby=affected&tableName=emdat&fromdate=&todate=

import requests
import json
import jsonpath

import pandas as pd

pd.set_option('display.max_columns', None)  # 显示完整的列
pd.set_option('display.max_rows', None)  # 显示完整的行
pd.set_option('display.expand_frame_repr', False)

df = pd.DataFrame()

for i in range(1, 136):
      url = 'https://www.gddat.cn/ssjc/disaster/getDisasterList?pageNo=' + str(
            i) + '&pageSize=20&eventtype=&countryname=&frequency=3650' \
                 '&orderby=affected&tableName=emdat&fromdate=&todate='

      response = requests.get(url)
      response.encoding = 'utf-8'
      content = response.text

      data = json.loads(content)
      data_list = jsonpath.jsonpath(data, '$..list.*')

      list1 = []
      for key, value in enumerate(data_list):
            my_list = list(value.values())
            continent = value.get('continent')
            country = value.get('country')
            code_two = value.get('code_two')
            enentparent = str(value.get('enentparent'))
            todate = value.get('todate')
            fromdate = value.get('fromdate')
            list1.append([continent, country, code_two, enentparent, todate, fromdate])
      print(list1)

      df = df._append(pd.DataFrame(list1))
df.to_csv('自然灾害.csv', index=False, header=True, encoding='utf-8')
print(df.shape)
print(df.info())

import pandas as pd
df = pd.read_csv(r'D:\BigData\pythonProject\爬虫\requests\自然灾害.csv')
# 重命名列名
df.columns = ['洲名', '国家', '国家简称', '灾害类型', '结束时间', '开始时间']
# 提取国家简称,供后续使用
df_abbr = df[['国家简称', '结束时间']]
df_abbr

# 对国家列进行处理
df['国家'] = df['国家'].str.split(',') # 根据逗号进行分隔
# df['国家简称'] = df['国家简称'].str.split(',')
# 把分隔开的数据展开成新的行
df = df.explode('国家',ignore_index=True)
df

# 对国家简称列进行拆分,同上
df_abbr['国家简称'] = df_abbr['国家简称'].str.split(',')
df_abbr = df_abbr.explode('国家简称', ignore_index=True)
df['国家简称'] = df_abbr['国家简称']
df

# 处理缺失值
df.isnull().sum()
df = df.dropna() # 删除为空的洲
df.reset_index(drop=True, inplace=True)

# 对灾害类型进行说明
# 1-地震、3-火山、4-洪涝、5-干旱、6-风暴、7-其他气象灾害、9-野火
for i in range(0, len(df)):
    data = df['灾害类型'][i]
    if data == 1:
        df['灾害类型'][i] = '地震'
    elif data == 3:
        df['灾害类型'][i] = '火山'
    elif data == 4:
        df['灾害类型'][i] = '洪涝'
    elif data == 5:
        df['灾害类型'][i] = '干旱'
    elif data == 6:
        df['灾害类型'][i] = '风暴'
    elif data == 7:
        df['灾害类型'][i] = '其他自然灾害'
    elif data == 9:
        df['灾害类型'][i] = '野火'
    elif data == 2:
        df['灾害类型'][i] = '地质灾害'
df

df['结束时间'] = pd.to_datetime(df['结束时间'])
df['开始时间'] = pd.to_datetime(df['开始时间'])
df['持续时长'] = df['结束时间'] - df['开始时间']
df

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = 'SimHei'    #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False    #用来显示负号
disaster = df['灾害类型'].value_counts() # 统计灾害的样本数量
plt.pie(disaster, labels=['地震', '火山', '洪涝', '干旱', '风暴', '其他自然灾害', '野火', '地质灾害'], autopct='%.1f%%')
plt.show()

# 使用pivot_table方法进行分组和聚合
grouped_df = df.pivot_table(index=['洲名', '灾害类型'], aggfunc='size').unstack(fill_value=0)

# 绘制堆叠条形图
grouped_df.plot(kind='bar', stacked=True, figsize=(10, 6))
plt.xlabel('洲名')
plt.ylabel('统计次数')
plt.title('国家和灾害类型分布')
plt.legend(title='灾害类型')
plt.xticks(rotation=0)
plt.show()

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 假设您的数据存储在一个名为df的DataFrame中
# df = pd.read_csv('your_data.csv')  # 从CSV文件中读取数据

# 进行数据预处理,将文本数据转换为数值型数据
label_encoder = LabelEncoder()
df['洲名'] = label_encoder.fit_transform(df['洲名'])
df['国家'] = label_encoder.fit_transform(df['国家'])
df['国家简称'] = label_encoder.fit_transform(df['国家简称'])
df['灾害类型'] = label_encoder.fit_transform(df['灾害类型'])

# 特征选择,假设我们只选取'洲名', '国家', '国家简称', '结束时间', '开始时间'作为特征
features = df[['洲名', '国家', '国家简称']]
target = df['灾害类型']

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.2, random_state=42)

# 建立随机森林分类器模型
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)

# 模型训练
rf_classifier.fit(X_train, y_train)

# 模型预测
y_pred = rf_classifier.predict(X_test)

# 计算模型准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率:{accuracy}")

文末:本文仅供学习使用,不支持任何商业或投资用途!

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jony..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值