Python实战:如何用ERA5数据计算风速风向(附完整代码)

张开发
2026/4/3 11:55:16 15 分钟阅读
Python实战:如何用ERA5数据计算风速风向(附完整代码)
Python实战ERA5数据中风速风向计算的完整指南气象数据分析工作中风速和风向的计算是基础但至关重要的环节。ERA5作为欧洲中期天气预报中心ECMWF提供的第五代全球大气再分析数据集包含了丰富的风场信息。本文将手把手教你如何用Python从ERA5数据中提取并计算风速风向并提供可直接运行的完整代码。1. 理解ERA5风场数据ERA5数据中的风场通常以U和V分量形式存储U分量表示东西方向的风速正值为西风从西向东吹负值为东风V分量表示南北方向的风速正值为南风从南向北吹负值为北风这两个分量共同构成了二维平面上的风矢量。要得到实际应用中的风速和风向需要进行矢量合成和角度计算。关键概念对比概念数学坐标系气象学坐标系0度基准X轴正方向正北方向角度增长方向逆时针顺时针风向表示风吹来的方向风吹来的方向2. 计算风速和风向的数学原理2.1 风速计算风速是U和V分量的矢量和模长计算公式简单直接wind_speed np.sqrt(U**2 V**2)2.2 风向计算风向计算需要考虑坐标系转换。气象学定义正北为0度顺时针增加角度而数学上的反正切函数返回的角度是基于X轴正方向东方向的。两种等效的计算方法# 方法一 wind_direction 180.0 np.arctan2(U, V) * (180.0/np.pi) # 方法二 wind_direction 270.0 - np.arctan2(V, U) * (180.0/np.pi)两种方法都能将风向转换到0-360度范围内结果完全一致。3. 完整Python实现下面是一个完整的Python脚本演示如何从ERA5数据文件中读取U、V分量并计算风速风向import xarray as xr import numpy as np import matplotlib.pyplot as plt # 加载ERA5数据 def load_era5_data(filepath): 加载ERA5 netCDF文件 try: ds xr.open_dataset(filepath) return ds except Exception as e: print(f加载数据失败: {e}) return None # 计算风速风向 def calculate_wind_components(u, v): 计算风速和风向 wind_speed np.sqrt(u**2 v**2) wind_direction (270 - np.arctan2(v, u) * 180/np.pi) % 360 return wind_speed, wind_direction # 主程序 def main(): # 替换为你的ERA5数据文件路径 era5_file era5_wind_data.nc # 加载数据 ds load_era5_data(era5_file) if ds is None: return # 选择特定时间和高度层 target_time 2024-05-01T12:00:00 target_level 850 # 850hPa等压面 try: # 筛选数据 ds_selected ds.sel( timetarget_time, leveltarget_level, methodnearest ) # 提取U、V分量 u_wind ds_selected.u v_wind ds_selected.v # 计算风速风向 speed, direction calculate_wind_components(u_wind, v_wind) # 可视化结果 plot_wind_results(u_wind, v_wind, speed, direction) except Exception as e: print(f数据处理出错: {e}) # 可视化函数 def plot_wind_results(u, v, speed, direction): 绘制风场结果 fig, (ax1, ax2, ax3) plt.subplots(1, 3, figsize(18, 6)) # U分量 u.plot(axax1, cmapcoolwarm) ax1.set_title(U Wind Component (m/s)) # V分量 v.plot(axax2, cmapcoolwarm) ax2.set_title(V Wind Component (m/s)) # 风速 speed.plot(axax3, cmapviridis) ax3.set_title(Wind Speed (m/s)) plt.tight_layout() plt.show() if __name__ __main__: main()4. 实际应用中的注意事项4.1 数据预处理要点单位检查确保U、V分量单位一致通常ERA5数据单位为m/s缺失值处理ERA5数据通常质量很高但仍需检查是否有NaN值坐标系统注意经度是否采用0-360度或-180到180度表示4.2 常见问题排查风向计算结果异常检查角度转换公式是否正确确认U、V分量顺序没有颠倒风速值不合理验证数据单位检查是否有异常值需要过滤可视化问题确保matplotlib版本兼容大数据量时考虑降采样显示4.3 性能优化技巧处理全球高分辨率ERA5数据时可采用以下优化方法# 使用Dask进行分块处理 ds xr.open_dataset(large_era5.nc, chunks{time: 10}) # 并行计算 from dask.distributed import Client client Client() speed, direction calculate_wind_components(ds.u, ds.v)5. 进阶应用风场分析与可视化5.1 风场矢量图def plot_wind_vectors(ds, level850, time_idx0): 绘制风场矢量图 plt.figure(figsize(12, 8)) # 选择特定高度和时间 u ds.u.isel(timetime_idx, levelds.levellevel) v ds.v.isel(timetime_idx, levelds.levellevel) # 降采样以提高可读性 stride 5 u_sub u[::stride, ::stride] v_sub v[::stride, ::stride] # 获取经纬度 lon u_sub.longitude.values lat u_sub.latitude.values # 绘制矢量图 plt.quiver(lon, lat, u_sub, v_sub, scale200) plt.title(fWind Vectors at {level}hPa) plt.xlabel(Longitude) plt.ylabel(Latitude) plt.show() # 使用示例 plot_wind_vectors(ds)5.2 风速风向剖面图def plot_wind_profile(ds, lat, lon, time_idx0): 绘制风速风向垂直剖面 # 选择最近格点 point ds.sel( latitudelat, longitudelon, methodnearest ).isel(timetime_idx) # 计算风速风向 speed, direction calculate_wind_components(point.u, point.v) # 创建图形 fig, (ax1, ax2) plt.subplots(1, 2, figsize(14, 8)) # 风速剖面 speed.plot(ylevel, axax1, markero) ax1.set_ylabel(Pressure Level (hPa)) ax1.set_xlabel(Wind Speed (m/s)) ax1.set_title(Wind Speed Profile) ax1.invert_yaxis() # 风向剖面 direction.plot(ylevel, axax2, markero, colororange) ax2.set_ylabel(Pressure Level (hPa)) ax2.set_xlabel(Wind Direction (degrees)) ax2.set_title(Wind Direction Profile) ax2.invert_yaxis() plt.tight_layout() plt.show() # 使用示例 plot_wind_profile(ds, lat40.0, lon116.0)6. 扩展应用风能评估案例基于ERA5风场数据我们可以进行初步的风能资源评估def wind_power_density(speed, air_density1.225): 计算风功率密度 (W/m²) return 0.5 * air_density * speed**3 # 计算年平均值 annual_mean_speed ds.u.groupby(time.year).mean(...) # 实际计算略 power_density wind_power_density(annual_mean_speed) # 可视化风能资源 plt.figure(figsize(10, 6)) power_density.plot(cmapjet) plt.title(Annual Mean Wind Power Density (W/m²)) plt.colorbar(labelPower Density (W/m²)) plt.show()

更多文章