爬取全球地质灾害信息(附网站+源码)
灾害是世界面临的共同挑战,为了更好地了解全球灾害的分布和趋势,我开发了一个基于 Python 的爬虫程序,从某网站上获取了近10年的全球灾害数据。通过数据分析和可视化,我揭示了不同洲际和国家的灾害分布,对灾害类型进行了分类,并通过模型训练预测了灾害的风险。在本博客中,我将与大家分享我整个研究的过程和结果。
数据爬取
使用 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')
通过对数据进行处理和清洗,得到了洲名、国家、国家简称、灾害类型、结束时间和开始时间六列数据。对于重复数据和缺失值,采用了去重和填充的方法,保证了数据的准确性和完整性。
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)
在灾害类型方面,我使用了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
在数据可视化方面,利用 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()
使用了机器学习的模型进行了灾害风险的预测。通过对历史数据的学习,建立一个预测模型,并通过准确率预测了未来可能发生的灾害风险,为防灾减灾工作提供了重要参考。
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}")
文末:本文仅供学习使用,不支持任何商业或投资用途!