原文:
towardsdatascience.com/climate-change-in-the-countryside-93e5ca66868b
快速成功数据科学
DALL-E3 的城市和乡村景观
我有一个亲戚认为气温上升只是“热岛”效应。也就是说,快速发展的钢铁和混凝土城市比绿色的乡村地区升温更快,保温时间更长。他说:“如果你专注于在较凉爽的乡村地区进行的温度测量,那么大部分全球变暖都会消失。”
数据科学的好处在于你可以成为自己的事实核查者。在这个快速成功数据科学项目中,我们将使用德克萨斯州这个伟大州份的温度数据来测试之前的假设。
什么是热岛?
根据美国环保署,热岛是比周边地区温度更高的城市化区域。人工结构,如建筑和道路,比自然景观,如森林和湖泊,吸收和重新辐射太阳的热量更多。人类活动,包括驾驶汽车和冷却建筑,会产生额外的热量。在大城市,这些结构和活动高度集中,相对于周边乡村,形成了高温“岛屿”。
2021 年 7 月的达拉斯-沃斯堡热岛(作者提供)
由于这种城市热岛效应,城市通常在白天更热,在夜间更暖。白天温度比乡村地区高约 1-7°F,夜间温度高约 2-5°F。
如果你只展示大型增长城市的温度数据,给人的印象将是全球气温比真正的全球平均值更高,并且上升速度更快。为了测试这一点,我们只需要比较大型城市区域和远小得多的乡村小镇的历史温度曲线。
策略
我们将考察两个大型城市区域和四个乡村小镇,其中三个位于德克萨斯州北部,三个位于德克萨斯州南部。在北部,我们将使用达拉斯,其西侧是阿尔巴尼,东侧是硫磺泉。
北部德克萨斯州使用的城市(红色框)(谷歌地图)
在南部,我们将使用圣安东尼奥,其西侧是洪多,东侧是卢宁。
南部德克萨斯州使用的城市(红色框)(谷歌地图)
以下表格总结了这些城市在 1950 年和 2023 年的人口数据,数据来源于美国人口普查局的公开数据。达拉斯和圣安东尼奥代表大城市区域。
选定城市的人口表(作者和美國人口普查局)
此处的目标是使用大致位于同一纬度线上的相对紧密排列的城市。德克萨斯州的盛行风来自西部,冷锋通常从北方向平原移动。保持城市相对靠近并在同一纬度上意味着它们应该经历相似的天气。
拥有这些数据,我们可以绘制并比较大城市和小城市的温度分布图,以查看它们是否遵循相似的趋势。
数据
在他的著作*未定:气候科学告诉我们什么,它没有告诉我们什么,以及为什么这很重要中,史蒂文·库宁使用美国政府的 2017 年气候科学特别报告来展示,每日记录低温的测量数量随着时间的推移以比每日记录高温增加更快的速度减少。因此,一个重要的气候变化信号隐藏在低温中,所以我们应该查看高和*低测量值。
我们可以在国家海洋和大气管理局 (NOAA) 管理的公共记录中找到我们选定城市的平均年最高和最低温度。我们将查看 1950 年至 2023 年之间的时期。这将给我们几乎 75 个数据点,并包括 1980 年左右温度快速上升之前的年份的概览。
为了方便起见,我已经收集了这些数据并将它们存储在代码片段中。我们将使用 URL 地址以编程方式访问它。
代码
以下代码是在 Jupyter Lab 中编写的。
导入库
我们只需要三个第三方库来完成这个项目的主体部分:Matplotlib、pandas 和 GeoPandas。
Matplotlib 是 Python 最受欢迎的绘图库。您可以在这里找到安装和使用说明。
Pandas 是 Python 的主要数据分析库。您可以在这里找到其安装和快速入门指南。
GeoPandas 扩展了 pandas 以处理地理空间数据。您可以在这里找到其安装和使用指南。
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
加载城市的地理空间数据
这样的研究通常包括一个“索引地图”,显示感兴趣的区域。因此,我们将首先绘制德克萨斯州的轮廓,并在其正确的地理空间位置和按其人口比例绘制城市。
以下代码使用 pandas 的read_csv()方法从 URL 加载城市纬度、经度和人口数据。然后显示完整的 DataFrame。
# Load the city data:
df_map = pd.read_csv('https://bit.ly/3XgMpIu')
df_map.head(6)
创建 GeoDataFrame
接下来,我们将 pandas DataFrame 转换为带有“geometry”新列的 GeoPandas GeoDataFrame。这个列以“point”几何格式存储经纬度数据。稍后,我们将使用这些点在地图上绘制城市。
gdf = gpd.GeoDataFrame(df_map, geometry=gpd.points_from_xy(df_map.Longitude,
df_map.Latitude))
gdf.head(6)
绘制索引地图
以下代码使用 Matplolib 绘制索引地图。然而,在这样做之前,我们需要德克萨斯州的轮廓,或者更具体地说,德克萨斯州的shapefile。
shapefile是一种常见的地理空间矢量数据格式,用于地理信息系统(GIS)软件。虽然我们使用了point几何格式来表示城市位置,但我们将使用polygon来表示州边界。
找到 shapefile 的一个方便的地方是Natural Earth 公共领域数据集。只需导航到这个网站,然后点击下面突出显示的黄色下载链接(版本号可能会随时间变化):
将压缩文件移动到包含您的 Python 脚本或笔记本的文件夹中,然后运行以下代码(您不需要解压文件夹)。
# Set-up the index map figure:
fig, ax = plt.subplots(figsize=(7, 6))
# Load the states shapefile as a GeoDataFrame:
states = 'ne_110m_admin_1_states_provinces.zip'
usa = gpd.read_file(states)
# Make a new GeoDataFrame with just Texas:
tx = usa[(usa.name == 'Texas')]
# Plot the outline of Texas:
tx.boundary.plot(ax=ax,
linewidth=1,
edgecolor='black')
# Plot the cities scaled by population:
gdf.plot(ax=ax,
markersize=gdf['Population'] / 2000,
color='firebrick')
# Annotate city names centered over the marker:
for x, y, label in zip(gdf.geometry.x, gdf.geometry.y, gdf['City']):
if label == 'Hondo':
horiz_align = 'right'
vert_align = 'bottom'
else:
horiz_align = 'left'
vert_align = 'center'
ax.annotate(label,
xy=(x, y),
xytext=(5, 2),
textcoords="offset points",
fontsize=8,
ha=horiz_align,
va=vert_align)
plt.title('Texas Cities Used in Study (Scaled by Population)')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.show()
研究中使用的 6 个城市,标记大小按人口比例缩放(作者制)
再次强调,标记大小代表城市的人口,而不是城市的边界。
更多关于 shapefile 的信息,请访问这篇文章:
加载温度数据
现在我们将加载每个城市的温度数据——存储为在线 CSV 文件——作为一个 pandas DataFrame。
# Read in city temperature data:
df_dallas = pd.read_csv('https://bit.ly/3WVtW2R')
df_albany = pd.read_csv('https://bit.ly/476rQSw')
df_sulphur = pd.read_csv('https://bit.ly/3Mhg6Tp')
df_san_antonio = pd.read_csv('https://bit.ly/3AKLQOa')
df_luling = pd.read_csv('https://bit.ly/4dSZ5e6')
df_hondo = pd.read_csv('https://bit.ly/4cCaMVC')
作为检查,显示达拉斯数据集的前五条记录:
df_dallas.head()
达拉斯 DataFrame 的头部(作者制)
定义一个函数来绘制年最高平均气温
我们需要绘制多个图表,所以接下来我们将定义一个函数,该函数接受两个 DataFrame 作为参数,并将每个的高温测量值作为同一图中的线图绘制。我只使用两个DataFrame,因为我发现很难理解同一图中的三个或更多曲线。
def plot_highs(df1, df2):
plt.plot(df1.Year, df1.High, color='firebrick', label=df1.City[0])
plt.plot(df2.Year, df2.High, color='grey', label=df2.City[0])
plt.title('Average Yearly High Temperatures (F)')
plt.xlabel('Year')
plt.ylabel('Average Yearly High Temperature (F)')
plt.legend()
plt.grid()
plt.legend();
定义一个函数来绘制年最低平均气温
接下来,我们重复之前的代码进行低温测量。
def plot_lows(df1, df2):
plt.plot(df1.Year, df1.Low, color='firebrick', label=df1.City[0])
plt.plot(df2.Year, df2.Low, color='gray', label=df2.City[0])
plt.title('Average Yearly Low Temperatures (F)')
plt.xlabel('Year')
plt.ylabel('Average Yearly Low Temperature (F)')
plt.grid()
plt.legend();
比较达拉斯和硫磺泉的最高气温
首先,我们将查看位于东北方向大约 80 英里(128 公里)的达拉斯和农村小镇硫磺泉。
plot_highs(df_dallas, df_sulphur)
达拉斯和阿尔巴尼的平均年最高气温(作者提供)
在这个图表中,有几个突出的事项。达拉斯通常比其他地方高几度,这与热岛效应一致。在 20 世纪 50 年代的史上干旱期间,气温非常高,然后在 60 年代和 70 年代有所降温(归因于工业和火山相关的硫酸盐气溶胶浓度高,反射阳光进入太空)。大约在 1980 年后,气温持续攀升至现在。
这两个城市的温度数据显示出相同的一般趋势。如果升温是由于热岛效应,我们预计硫磺泉的曲线将在 1980 年后变平,而不是跟随达拉斯曲线。
比较达拉斯和阿尔巴尼的最高气温
现在,让我们看看位于西方向大约 150 英里(240 公里)的达拉斯和农村小镇阿尔巴尼。
plot_highs(df_dallas, df_albany)
达拉斯和阿尔巴尼的平均年最高气温(作者提供)
曲线相似,遵循相同的趋势。
比较圣安东尼奥和洪多的最高气温
现在,让我们向南移动大约 270 英里(432 公里),并查看位于西方向大约 44 英里(70 公里)的圣安东尼奥和农村小镇洪多。
plot_highs(df_san_antonio, df_hondo)
圣安东尼奥和洪多的平均年最高气温(作者提供)
奇怪的是,洪多的温度往往高于远大于其的城市圣安东尼奥。然而,它们显示出相同的趋势,这表明没有热岛效应偏误结果。
比较圣安东尼奥和卢林的最高气温
这是圣安东尼奥与东北方向大约 57 英里(91 公里)的农村小镇卢林的比较结果。
plot_highs(df_san_antonio, df_luling)
圣安东尼奥和卢林的平均年最高气温(作者提供)
这些曲线非常相似,除了少数异常之外,彼此之间跟踪得很好。
比较达拉斯和硫磺泉的最低气温
现在让我们看看低温数据。记住,气候变化的一个方面似乎就是记录最低温度的数量随着时间的推移在减少。
这是达拉斯和硫磺泉的比较:
plot_lows(df_dallas, df_sulphur)
达拉斯和硫磺泉的平均年最低气温(作者提供)
这里的温度分离是显著的,但仍在热岛效应观察到的行为范围内。关键结论是,从 20 世纪 80 年代初开始,两条曲线以大致相同的速率增加。
比较达拉斯和阿灵顿的最低气温
下面是达拉斯和阿灵顿的低温比较:
plot_lows(df_dallas, df_albany)
达拉斯和阿灵顿的平均年最低气温(作者)
这个图更像是如果气候变化相关的温度变化受到热岛效应的严重影响,我会期望看到的。大约在 1980 年后,达拉斯的年平均低温总体上升,而农村的阿灵顿则趋于平稳,尽管在最后十年左右,它们更接近于达拉斯。
比较圣安东尼奥和洪多的最低气温
下面是圣安东尼奥和洪多的低温比较:
plot_lows(df_san_antonio, df_hondo)
圣安东尼奥和洪多的平均年最低气温(作者)
这两条曲线相当好地相互跟踪,尽管洪多的曲线在 1980 年至 2010 年间看起来相当平坦。
比较圣安东尼奥和卢林的最低气温
下面是圣安东尼奥和卢林的低温比较:
plot_lows(df_san_antonio, df_luling)
圣安东尼奥和卢林的平均年最低气温(作者)
与圣安东尼奥-洪多曲线相比,卢林的农村测量值在 1999 年至 2013 年左右与圣安东尼奥的读数出现分歧。此后,它们迅速恢复并紧密跟随大城市的行为。
比较圣安东尼奥和达拉斯
为了好玩,让我们比较一下圣安东尼奥和达拉斯。由于位于更南的地方,我们预计圣安东尼奥会更暖和,事实也是如此。曲线也以相似的斜率上升。
plot_highs(df_san_antonio, df_dallas)
圣安东尼奥和达拉斯的平均年最高气温(作者)
plot_lows(df_san_antonio, df_dallas)
圣安东尼奥和达拉斯的平均年最低气温(作者)
这最后两条曲线并不能很好地解决城市与农村的问题,但它们表明过去 73 年间德克萨斯州的气温变化是相似的。
定量增加的温度(1980-2023)
一种更定量的方法是,在将数据集过滤到 1980-2023 年区间后,对北部和南部的农村数据集分别拟合回归线。这代表了最近 warming 趋势确立的时期。
我们需要NumPy(数值 Python)和scikit-learn(机器学习)库。您可以在之前的链接中找到安装说明。
这里是一个示例代码片段,用于组合并绘制南部 Hondo 和 Luling 数据框:
import numpy as np
from sklearn.metrics import r2_score
# Filter southern rural Dfs to 1980 and after:
df_hondo_80 = df_hondo[df_hondo['Year'] >= 1980]
df_luling_80 = df_luling[df_luling['Year'] >= 1980]
# Merge the DFs into one:
rural_south_df = pd.concat([df_hondo_80, df_luling_80],
ignore_index=True)
# Plot a Scattergram:
plt.scatter(rural_south_df['Year'],
rural_south_df['Low'],
color='grey',
label='Rural South Low Temps')
# Fit a regression line with NumPy:
slope, intercept = np.polyfit(rural_south_df['Year'],
rural_south_df['Low'], 1)
regression_line = slope * rural_south_df['Year'] + intercept
plt.plot(rural_south_df['Year'],
regression_line,
color='firebrick',
label='Regression line')
# Calculate R-squared value with sklearn:
r_squared = r2_score(rural_south_df['Low'], regression_line)
# Add equation and R-squared value to the plot:
equation_text = f'y = {slope:.2f}x + {intercept:.2f}n$R²$ = {r_squared:.2f}'
plt.text(0.05, 0.95,
equation_text,
transform=plt.gca().transAxes,
fontsize=12,
verticalalignment='top',
bbox=dict(boxstyle='round,pad=0.5',
edgecolor='black',
facecolor='white'))
# Add labels and title:
plt.xlabel('Year')
plt.ylabel('Low')
plt.title('Rural South Average Yearly Low Temperatures (1980-2023)')
plt.legend(loc='lower right')
# Show plot
plt.show()
这里是高温和低温的结果。两条回归线都有正斜率,表明这一时期气温上升:
1980 年至 2023 年农村南部高温(左)和低温(右)的散点图(作者提供)
北部的两个农村城市显示出相似但更微弱的结果:
1980 年至 2023 年农村北部高温(左)和低温(右)的散点图(作者提供)
这些回归线证实了我们在线性图中观察到的增长。
概要
仅对六个城市进行初步考察,很明显,城市和农村地区都对气候变化有类似的反应。全球变暖并不是仅展示热岛数据造成的城市数据“假象”。
附加项目:比较温度和人口趋势
作为附加项目,比较一个城市的温度趋势与其人口增长。以下是以达拉斯为例,使用达拉斯-沃斯堡大都市区的数据:
达拉斯-沃斯堡平均年最高气温与人口增长对比图(作者提供)
达拉斯-沃斯堡平均年最低气温与人口增长对比图(作者提供)
根据美国环境保护署Environmental Protection Agency的数据,一个只有一百万人口的城市可以表现为城市热岛。这意味着 DFW 大都市区早在 20 世纪 50 年代初就已经是热岛了。
更多气候变化项目
如果您喜欢使用 Python 探索气候变化主题,请务必查看以下项目:
感谢!
感谢阅读,请关注我,未来将有更多快速成功数据科学项目。
918

被折叠的 条评论
为什么被折叠?



