在当今数据驱动的时代,气象数据的获取、处理和可视化已成为气象科学研究和业务应用中不可或缺的环节。Python作为一种功能强大且灵活的编程语言,已经在气象数据处理和可视化领域展现出了巨大的潜力。它不仅提供了丰富的库和工具,如`matplotlib`和`cartopy`,用于数据的科学绘图与可视化,还支持多种数据格式的处理,如`NetCDF`、`GRIB`、`HDF`。此外,Python还能够高效地下载和预处理气象数据,例如利用`cdsapi`和`IDM`批量下载`ERA5`数据。
本文旨在介绍如何使用Python进行气象数据的下载、预处理、统计分析以及科学绘图与可视化。通过本文的介绍,读者可以能够掌握使用Python进行气象数据处理和可视化的基本技能,作者也可以唤起尘封的记忆,整理一下以前的笔记,为进一步的气象研究和应用打下坚实的基础。
ERA5是由欧洲中期天气预报中心(ECMWF)提供的第五代全球气候大气再分析数据集,覆盖了从1940年1月至今的时期。它由ECMWF的哥白尼气候变化服务(C3S)生产,提供了大量大气、陆地和海洋气候变量的每小时估计值。这些数据覆盖了30公里网格上的地球,并使用137个从地表到80公里高度的高度来解析大气,包括在降低空间和时间分辨率时所有变量的不确定性信息。ERA5将模型数据与来自世界各地的观测数据结合起来,形成一个全球完整的、一致的数据集,取代了其前身ERA-Interim再分析。
CDS平台,即气候数据存储(Climate Data Store),是一个提供气候和气象数据的平台,它允许用户访问和下载各种气候数据集,包括ERA5数据。CDS平台提供了强大的数据管理功能,包括数据收集、存储、整理、清洗和分类等。通过构建高效的数据处理机制,CDS确保了数据的准确性和一致性,为后续的数据分析和算法迭代提供了可靠的基础。为了更直观地展示数据,CDS平台还提供了丰富的数据可视化组件,用户可以根据自己的需求,自由配置可视化界面,实现数据的直观展示和交互。
可以在Datasets里查找需要的数据,收藏经常使用的数据,可以在个人profile里轻松找到。
关于利用cdsapi+IDM批量下载ERA5数据的教程帖子非常多,主要步骤是:
1)注册/登陆后打开CDS上的个人主页,找到API,复制url和key
2)获取API Token后在用户目录下配置.cdsapirc文件
3)下载安装cdsapi第三方库
4)下载安装IDM-Internet Download Manager,IDMan.exe的路径要记住,后面写代码要用
5)获取所需要数据的API request code,如下
6)编写批量下载Python代码
展示主要代码:
import cdsapi
import os
from subprocess import call
def idmDownloader(task_url, folder_path, file_name):
"""
IDM下载器
:param task_url: 下载任务地址
:param folder_path: 存放文件夹
:param file_name: 文件名
:return:
"""
# IDM安装目录
idm_engine = "C:\\Program Files (x86)\\Internet Download Manager\\IDMan.exe"
# 将任务添加至队列
call([idm_engine, '/d', task_url, '/p', folder_path, '/f', file_name, '/a'])
# 开始任务队列
call([idm_engine, '/s'])
c = cdsapi.Client()
for date_str in extreme_dates:
year, month, day = date_str.split('-')
year_path = os.path.join(path, year) # 创建每年的文件夹
os.makedirs(year_path, exist_ok=True) # 如果文件夹不存在则创建
filename = f'{variable}.0.25deg.{year}.{month}.{day}.nc'
output_file_path = os.path.join(year_path, filename)
# 检查文件是否已存在
if os.path.exists(output_file_path):
print(f'文件 {output_file_path} 已存在,跳过下载。')
continue
print(f'======= 日期: {date_str} =======')
r = c.retrieve(
'derived-era5-pressure-levels-daily-statistics',
{
'product_type': 'reanalysis',
'variable': ["geopotential",
"specific_humidity",
"u_component_of_wind",
"v_component_of_wind",
"vertical_velocity"],
'year': [year],
'month': [month],
'day': [day],
"pressure_level": ["500"],
"daily_statistic": "daily_mean",
"time_zone": "utc+08:00",
"frequency": "1_hourly",
"area": [80, 30, 5, 150]
},
)
url = r.location # 获取文件下载地址
idmDownloader(url, year_path, filename) # 添加进IDM中下载
最后就静待数据自己跑到文件夹里吧~
GPM(Global Precipitation Measurement,全球降水测量)数据是由美国国家航空航天局(NASA)和日本宇宙航空研究开发机构(JAXA)联合开展的一项国际卫星任务,旨在提供全球范围内的高精度降水数据。
GPM数据通过多颗卫星的联合观测获得,这些卫星搭载了微波和红外传感器,能够测量降雨和降雪等降水类型。此外,GPM还结合了地面雷达和雨量计的观测数据,进一步提高数据的准确性和可靠性。
下载网站:
https://disc.gsfc.nasa.gov/
记得先注册/登陆在检索下载数据。
GPM数据是一日一个文件,大量数据逐个下载的话很繁琐,我尝试了很多办法,发现还是用downthemall插件下载最方便且下载成功率最高。
如果先下载文件链接的txt文件,再逐个下载数据,我反正常遇到网址错误或下载失败的问题。
建议一次性也不要下太多数据,不然出错率蛮高,还得返工。
选择自己需要的数据。
为撒不能收藏啊???
气象海洋数据的存储格式多种多样,不同的格式适用于不同的应用场景和数据处理需求。
nc格式数据非常常见,文件中包含数据的元信息(如变量名称、单位、坐标轴等),便于数据的读取和理解。
支持大数据量存储,适合存储多维气象和海洋数据(如温度、湿度、风场等)。
可以print出来看看内容,也可以直接使用panoply可视化出来。
GRIB(General Regularly-distributed Information in Binary form)是由世界气象组织(WMO)设计和维护的一种用于存储和传输网格数据的标准数据格式。它是一种自描述的二进制压缩格式,主要用于气象和海洋科学领域,尤其适用于存储数值天气预报模型的输出数据。GRIB主要用于存储规则格点数据,适用于气象模型输出、卫星数据等。
GRIB文件由多个“报文”(Message)组成,每个报文包含一套完整的数据及其描述信息。报文结构包括多个部分(Section)。
pygrib 和 cfgrib:Python库,用于在Python环境中处理GRIB数据。
HDF(Hierarchical Data Format,层次数据格式)是一种用于存储和管理大规模、复杂科学数据的自描述、多对象的二进制文件格式。它广泛应用于气象、海洋、生物、天文学等多个科学领域。
HDF文件采用类似文件系统的层次结构,包含“组”(Group)和“数据集”(Dataset)。组类似于文件夹,用于组织数据;数据集类似于文件,用于存储实际数据。
HDF文件由多个“组”和“数据集”组成,每个数据集包含实际数据和与之相关的元数据。例如,一个气象数据的HDF文件可能包含多个组,每个组代表不同的气象变量(如温度、风速等),每个组下又有多个数据集,存储不同时间或空间的数据。
HDF有多个版本,其中HDF5是当前主流版本。HDF5提供了一个更高效、更灵活的数据模型,支持复杂的多维数据结构和高效的I/O操作。
常用的处理工具:
h5py:Python中用于操作HDF5文件的库,支持读写HDF5文件。
HDFView:一个可视化工具,用于浏览和编辑HDF文件。
GDAL:用于地理空间数据处理的工具,支持HDF格式的读取。
Shapefile 是一种广泛使用的地理空间数据格式,主要用于存储地理信息系统的(GIS)矢量数据,如点、线、多边形等几何对象及其属性信息。它由美国环境系统研究所公司(ESRI,Environmental Systems Research Institute)开发,并已成为地理空间数据交换的事实标准。
Shapefile 实际上是一个文件集合,每个 Shapefile 至少包含以下三个核心文件:
1).shp 文件
内容:存储几何对象(点、线、多边形)的二进制数据。
作用:定义地理空间数据的几何形状,如经纬度坐标、几何拓扑结构等。
2).shx 文件
内容:索引文件,用于快速定位 .shp 文件中的几何对象。
作用:提高数据读取效率,尤其在处理大规模数据时。
3).dbf 文件
内容:以 dBase IV 格式存储几何对象的属性信息。
作用:为每个几何对象提供描述性信息,如名称、类别、数值等。
Shapefile 支持点(Point)、线(Polyline)、多边形(Polygon)等多种几何类型,能够满足大多数地理空间数据的存储需求。
不同的shapefile文件储存格式有所不同,重要的是需要找到所需区域的多边形数据存储的位置。
在Python中,可以使用多种库来打开和查看NetCDF(.nc)文件。
1)xarray
import xarray as xr
# 打开文件
ds = xr.open_dataset('example.nc')
# 查看数据集的基本信息
print(ds)
# 读取某个变量的数据
temperature = ds['temperature'].values
print("Temperature Data:", temperature)
# 关闭数据集
ds.close()
2)netCDF4
import netCDF4 as nc
# 打开文件
dataset = nc.Dataset('example.nc', 'r')
# 查看文件中的维度和变量
print("Dimensions:", dataset.dimensions.keys())
print("Variables:", dataset.variables.keys())
# 读取某个变量的数据
temperature = dataset.variables['temperature'][:]
print("Temperature Data:", temperature)
# 关闭文件
dataset.close()
1)netCDF4索引:
使用数组切片语法(如[0, :, :])直接索引数据。
需要明确变量的维度顺序(通常是时间、纬度、经度)。
import netCDF4 as nc
# 打开NetCDF文件
dataset = nc.Dataset('example.nc', 'r')
# 查看文件中的变量
print("Variables:", dataset.variables.keys())
# 索引并读取特定变量的数据
temperature = dataset.variables['temperature'][:] # 读取所有数据
temperature_at_time_0 = dataset.variables['temperature'][0, :, :] # 索引时间维度的第一个时间点
temperature_at_lat_0_lon_0 = dataset.variables['temperature'][:, 0, 0] # 索引特定经纬度点
print("Temperature Data:", temperature)
print("Temperature at Time 0:", temperature_at_time_0)
print("Temperature at Lat 0, Lon 0:", temperature_at_lat_0_lon_0)
# 关闭文件
dataset.close()
2)xarray索引:
使用.isel()方法进行基于位置的索引。
支持更直观的多维索引,适合复杂数据操作。
import xarray as xr
# 打开NetCDF文件
ds = xr.open_dataset('example.nc')
# 查看数据集信息
print(ds)
# 索引特定变量的数据
temperature = ds['temperature'] # 获取温度变量
temperature_at_time_0 = temperature.isel(time=0) # 索引时间维度的第一个时间点
temperature_at_lat_0_lon_0 = temperature.isel(lat=0, lon=0) # 索引特定经纬度点
print("Temperature Data:", temperature)
print("Temperature at Time 0:", temperature_at_time_0)
print("Temperature at Lat 0, Lon 0:", temperature_at_lat_0_lon_0)
# 关闭数据集
ds.close()
slice是一个内置对象,用于表示序列(如列表、元组、字符串等)的切片操作。它通常用于提取序列中的一部分数据,而不需要重新创建整个序列。
slice(start, stop, step)
裁剪国界、省界、市界等需要借助shapefile文件,也就是白化。
白化、掩膜、按区域裁剪,感觉都差不多,即将不需要的研究区域白化处理,凸显出研究区域。
介绍一种白化裁剪方法。这个方法比较简单粗暴。
import rioxarray
import geopandas
from shapely. geometry import mapping
#设置数据集的空间维度(也称为地理或空间坐标)并编写坐标参考系统(crs)。 EPSG4326 坐标系,也称为 WGS 84(世界大地测量系统 1984),是地理数据常用的坐标系
data.rio.set_spatial_dims(x_dim="lon", y_dim="lat", inplace=True) # x_dim具体是什么,看自己的nc文件变量名
data.rio.write_crs("epsg:4326", inplace=True)
# 将非空间变量设置为坐标,避免干扰裁剪操作
data = data.set_coords(["time_bnds"]) # 如果nc文件里有lon_bnds啥的也要加上
hunan = geopandas.read_file('C:/Users/lenovo/Desktop/湖南无子区域/湖南省行政边界.shp', crs="epsg:4326") # 该shp只含湖南省界
clipped = data.rio.clip(hunan.geometry.apply(mapping), hunan.crs, drop=True)
print(clipped)
白化主要有两种思路:
1)先白化数据,在绘图
这样画出来的图不太好看,边界像锯齿,磕巴。但如果只要研究区域内的数据,就得先处理数据。
2)先画矩形区域,再白化图形
这样画图边界更好看,如果只有可视化需求,建议先画图再白化。
插值的方法很多。
1)最近邻插值(Nearest Neighbor Interpolation)
最近邻插值是一种简单的插值方法,通过找到目标点最近的观测站点,直接将该站点的值赋予目标点。这种方法的优点是计算速度快,但插值结果较为粗糙,不适用于需要平滑过渡的场景。
2)反距离加权插值(Inverse Distance Weighting, IDW)
反距离加权插值是一种基于距离的加权平均方法,权重与距离的倒数成正比。这种方法适用于气象数据的插值,尤其是当观测站点分布不均匀时。它能够生成较为平滑的结果,但可能会在边界处出现偏差。
3)克里金插值(Kriging)
克里金插值是一种基于统计学的插值方法,适用于具有空间相关性的数据。它通过建模半方差函数来估计空间相关性,并生成最优的无偏插值结果。克里金插值能够提供更精确的插值结果,但计算复杂度较高。
4)样条插值(Spline Interpolation)
样条插值是一种基于多项式的插值方法,能够生成平滑的曲线或曲面。它适用于需要高精度插值的场景,但可能会在数据边界处出现震荡。
5)多元回归分析法(Multiple Regression Analysis)
多元回归分析法是一种基于统计模型的插值方法,适用于具有多个影响因素的数据。它通过建立线性或非线性模型来预测目标变量的值,适用于气象要素的时空插值。
完整示例代码:
#coding=gbk
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
# 1. 打开数据
file_path = r'C:/path/to/your/data.nc' # 替换为你的NC文件路径
ds = xr.open_dataset(file_path)
# 打印数据集信息
print(ds)
# 2. 索引数据
# 假设数据集中有一个变量名为'temperature',维度为(time, lat, lon)
temperature = ds['temperature'] # 提取温度变量
print(temperature)
# 3. 裁剪数据
# 假设需要裁剪到特定区域(如纬度20°-40°,经度100°-120°)
lat_range = slice(20, 40) # 纬度范围
lon_range = slice(100, 120) # 经度范围
temperature_cropped = temperature.sel(lat=lat_range, lon=lon_range)
print(temperature_cropped)
# 4. 白化(掩膜处理)
# 假设需要掩膜掉海洋区域(海洋值为NaN)
# 这里假设海洋区域的温度值为NaN
temperature_masked = temperature_cropped.where(~np.isnan(temperature_cropped))
print(temperature_masked)
# 5. 插值
# 假设需要将数据插值到更精细的网格(如0.1°×0.1°)
# 原始网格
lon_original = temperature_masked.lon.values
lat_original = temperature_masked.lat.values
# 新网格
new_lon = np.linspace(lon_original.min(), lon_original.max(), int((lon_original.max() - lon_original.min()) / 0.1))
new_lat = np.linspace(lat_original.min(), lat_original.max(), int((lat_original.max() - lat_original.min()) / 0.1))
new_lon, new_lat = np.meshgrid(new_lon, new_lat)
# 插值(使用线性插值)
temperature_interpolated = griddata(
(lon_original.flatten(), lat_original.flatten()), # 原始网格点
temperature_masked.values.flatten(), # 原始数据
(new_lon, new_lat), # 新网格点
method='linear' # 插值方法:linear, nearest, cubic
)
# 6. 可视化结果
plt.figure(figsize=(10, 6))
plt.contourf(new_lon, new_lat, temperature_interpolated, levels=20, cmap='coolwarm')
plt.colorbar(label='Temperature (°C)')
plt.title('Interpolated Temperature')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.show()
# 7. 保存处理后的数据(可选)
output_path = r'C:/path/to/your/processed_data.nc' # 替换为输出路径
temperature_interpolated_ds = xr.Dataset(
{
'temperature': (['lat', 'lon'], temperature_interpolated)
},
coords={
'lon': new_lon[0, :], # 新经度坐标
'lat': new_lat[:, 0] # 新纬度坐标
}
)
temperature_interpolated_ds.to_netcdf(output_path)
print(f"处理后的数据已保存至:{output_path}")
NumPy 是Python中用于科学计算的基础库,提供了高性能的多维数组对象(ndarray
)以及用于操作这些数组的工具。
xarray 是一个基于 NumPy 的库,专门用于处理多维数据(如气象、海洋数据)。它提供了更高级的接口,使得数据操作更加直观和方便。
scikit-learn 是一个广泛使用的机器学习库,提供了简单且高效的工具用于数据挖掘和数据分析。它提供了多种监督学习(如线性回归、逻辑回归、支持向量机、决策树等)和无监督学习(如聚类、降维等)算法
基本思路是处理好数据,确定想要展现出的图片形式,画就完了。panoply也可以一键可视化nc、hdf等数据。
matplotlib是Python中最常用的科学绘图库之一,提供了丰富的绘图功能,可以生成各种静态、动画和交互式图表和各种子图排布,非常灵活。
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
axes[0, 0].plot(x, np.sin(x), label="sin(x)")
axes[0, 1].plot(x, np.cos(x), label="cos(x)")
axes[1, 0].plot(x, np.tan(x), label="tan(x)")
axes[1, 1].plot(x, np.exp(-x), label="exp(-x)")
for ax in axes.flatten():
ax.legend()
ax.grid(True)
plt.tight_layout()
plt.show()
cartopy是一个基于matplotlib的地理空间数据可视化库,专门用于绘制地图和地理数据。它提供了丰富的地图投影和地理数据处理功能,非常适合气象、海洋和地理科学领域。
支持多种地图投影,可以利用matplotlib的绘图功能进行定制化。
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
# 创建地图
fig, ax = plt.subplots(figsize=(10, 6), subplot_kw={"projection": ccrs.PlateCarree()})
# 添加地图元素
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=":")
ax.add_feature(cfeature.LAND, facecolor="lightgray")
ax.add_feature(cfeature.OCEAN, facecolor="lightblue")
# 设置地图范围
ax.set_extent([70, 140, 15, 55], crs=ccrs.PlateCarree()) # 经纬度范围
# 添加标题
ax.set_title("China Map", fontsize=16)
plt.show()
绘制地理数据
import xarray as xr
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
# 加载NetCDF数据
ds = xr.open_dataset("example.nc")
temperature = ds['temperature'].isel(time=0)
# 创建地图
fig, ax = plt.subplots(figsize=(10, 6), subplot_kw={"projection": ccrs.PlateCarree()})
# 添加地图元素
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=":")
ax.add_feature(cfeature.LAND, facecolor="lightgray")
# 绘制数据
temperature.plot(ax=ax, transform=ccrs.PlateCarree(), cmap="coolwarm", add_colorbar=True)
# 设置地图范围
ax.set_extent([70, 140, 15, 55], crs=ccrs.PlateCarree())
# 添加标题
ax.set_title("Temperature Distribution", fontsize=16)
plt.show()
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。