You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速44年ERA5格点风速百分位数计算代码?

优化NetCDF单点风速百分位数计算速度的方案

问题背景

需要计算NetCDF文件中某一经纬度格点44年的风速百分位数,现有528个100m u分量和528个100m v分量文件(单个文件1.4G),原代码运行极慢,需求优化。

原代码:

import os
import numpy as np
import xarray as xr

data_folder1 = 'K:\\reanalysis\ERA5\\100m_speed\\100m u\\1979-2022'
data_folder2 = 'K:\\reanalysis\ERA5\\100m_speed\\100m v\\1979-2022'

file_names_u = os.listdir(data_folder1)
file_names_v = os.listdir(data_folder2)

def read_wind(file_path_u, file_path_v, lat_value, lon_value):
    with xr.open_dataset(file_path_u) as ds:
        u_wind = ds['u100'].sel(latitude=lat_value, longitude=lon_value).values
    with xr.open_dataset(file_path_v) as ds:
        v_wind = ds['v100'].sel(latitude=lat_value, longitude=lon_value).values
    return u_wind, v_wind

lat_value = 0
lon_value = 90
all_u_winds = []
all_v_winds = []

for file_name_u, file_name_v in zip(file_names_u, file_names_v):
    file_path_u = os.path.join(data_folder1, file_name_u)
    file_path_v = os.path.join(data_folder2, file_name_v)
    u_wind, v_wind = read_wind(file_path_u, file_path_v, lat_value, lon_value)
    all_u_winds.extend(u_wind)
    all_v_winds.extend(v_wind)

all_u_winds = np.array(all_u_winds)
all_v_winds = np.array(all_v_winds)

# 计算风速
all_windspeeds = np.sqrt(np.square(all_u_winds) + np.square(all_v_winds))

percentile_50 = np.percentile(all_windspeeds, 50)
print(f"The 50% percentile of the wind speed values is: {percentile_50}")

优化方案

1. 批量读取文件,削减IO开销

原代码循环打开单个文件导致频繁磁盘IO,改用xarray.open_mfdataset批量加载所有文件,直接提取目标格点数据:

import os
import numpy as np
import xarray as xr

data_folder_u = 'K:\\reanalysis\\ERA5\\100m_speed\\100m u\\1979-2022'
data_folder_v = 'K:\\reanalysis\\ERA5\\100m_speed\\100m v\\1979-2022'

# 批量读取u分量,分块加载避免内存溢出
ds_u = xr.open_mfdataset(os.path.join(data_folder_u, '*.nc'), chunks={'time': 1000})
u_data = ds_u['u100'].sel(latitude=0, longitude=90).values.flatten()

# 批量读取v分量
ds_v = xr.open_mfdataset(os.path.join(data_folder_v, '*.nc'), chunks={'time': 1000})
v_data = ds_v['v100'].sel(latitude=0, longitude=90).values.flatten()

# 计算风速与百分位数
windspeeds = np.sqrt(u_data**2 + v_data**2)
p50 = np.percentile(windspeeds, 50)
print(f"50%风速百分位数: {p50}")

2. 分块并行计算,利用多CPU资源

通过dask分块处理数据,让xarray自动并行加载和计算,进一步提升效率:

import os
import xarray as xr

data_folder_u = 'K:\\reanalysis\\ERA5\\100m_speed\\100m u\\1979-2022'
data_folder_v = 'K:\\reanalysis\\ERA5\\100m_speed\\100m v\\1979-2022'

# 批量读取并设置分块
ds_u = xr.open_mfdataset(os.path.join(data_folder_u, '*.nc'), chunks={'time': 2000})
ds_v = xr.open_mfdataset(os.path.join(data_folder_v, '*.nc'), chunks={'time': 2000})

# 直接在数据集上计算目标格点风速
windspeed = xr.ufuncs.sqrt(ds_u['u100'].sel(latitude=0, longitude=90)**2 + ds_v['v100'].sel(latitude=0, longitude=90)**2)

# 计算百分位数(自动用dask并行处理)
p50 = windspeed.quantile(0.5).values
print(f"50%风速百分位数: {p50}")

3. 核心优化点说明

  • 减少IO次数:批量读取替代循环单文件操作,大幅降低磁盘IO开销;
  • 精准加载数据:提前用sel提取目标经纬度,避免加载全局数据,减少内存占用;
  • 分块并行:通过chunks参数让xarray调用dask分块处理,利用多CPU核心并行计算;
  • 避免内存冗余:直接从数据集提取numpy数组,省去列表扩展再转换的额外开销。

额外建议

  • 确保u、v分量文件的时间维度完全对齐,避免时间序列混乱;
  • 若磁盘IO是瓶颈,将文件迁移至SSD存储;
  • 可手动启动dask客户端调整并行资源:
    from dask.distributed import Client
    client = Client(n_workers=4)  # 根据CPU核心数设置
    

内容的提问来源于stack exchange,提问作者czhhhhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:26:20