python代码简洁,提高运行速度


ds1 = xr.open_dataset('d:/history_weather/%s'% (time)+'/CDS%s'% (time)+'ts-s.nc')
ds = xr.open_dataset('d:/history_weather/%s'% (time)+'/CDS%s'% (time)+'ts-h.nc')
lon = ds1['longitude']#读取经度
lat = ds1['latitude']#读取纬度   
lon_range = lon[(lon>117) & (lon<124)]
lat_range = lat[(lat>24) & (lat<33)]
lons,lats=np.meshgrid(lon_range,lat_range)#网格化
lon_2d, lat_2d = np.meshgrid(lon, lat)
lon_2d[lon_2d > 180] = lon_2d[lon_2d > 180] - 360
for hour in hours:
    ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)
    wind_shear(ds, lon_range, lat_range, lons, lats, time, ds_time)
for hour in hours:
    ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)            
    draw_fet(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
for hour in hours:
    ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)            
    draw_vert(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
for hour in hours:
    ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)            
    draw_vf(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
for hour in hours:
    ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)            
    draw_vort(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
for hour in hours:
    ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)            
    draw_w(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
for hour in hours:
    ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)            
    draw_index(ds1, lon_range, lat_range, lons, lats, time, ds_time)

此段代码,因为每读取一次数据后,运行函数计算并绘图都需要时间,所以分了7次for循环,减少计算的时间,而不是一个for中需要7次计算。
以wind_shear为例,单独的for循环中,计算一次后再按不同hour绘图7次即可,而整体的for循环需要7次计算再7次绘图。
所以有没有什么方式使得更加简洁,同时提高运行速度。

你说的计算是哪一部分?
你这样分成7次后明显多计算了几次 ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)
放在一个for循环里只需要计算一次ds_time 就行

该回答引用ChatGPT

代码如下

import xarray as xr
import numpy as np

def draw_all(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time):
    draw_fet(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_vert(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_vf(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_vort(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_w(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_index(ds1, lon_range, lat_range, lons, lats, time, ds_time)

time = '202201'
year, month, day = time[:4], time[4:6], time[6:8]
hours = ['00', '06', '12', '18']

ds1 = xr.open_dataset('d:/history_weather/%s/CDS%sts-s.nc'% (time, time)).isel(longitude=slice(117,124), latitude=slice(24,33))
ds = xr.open_dataset('d:/history_weather/%s/CDS%sts-h.nc'% (time, time)).isel(longitude=slice(117,124), latitude=slice(24,33))
lon = ds1['longitude']
lat = ds1['latitude']
lons,lats=np.meshgrid(lon,lat)
lon_2d, lat_2d = np.meshgrid(ds['longitude'], ds['latitude'])
lon_2d[lon_2d > 180] = lon_2d[lon_2d > 180] - 360

for hour in hours:
    ds_time = '%s-%s-%sT%s'%(year, month, day, hour)            
    draw_all(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)


参考GPT的内容和自己的思路,对代码做了优化,优化后代码如下:

import numpy as np
import xarray as xr
from joblib import delayed, Parallel

def load_data(time):
    ds1 = xr.open_dataset(f'd:/history_weather/{time}/CDS{time}ts-s.nc')
    ds = xr.open_dataset(f'd:/history_weather/{time}/CDS{time}ts-h.nc')
    lon = ds1['longitude']
    lat = ds1['latitude']
    lon_range, lat_range = np.meshgrid(
        lon.where((lon > 117) & (lon < 124)),
        lat.where((lat > 24) & (lat < 33))
    )
    lon_2d, lat_2d = np.meshgrid(lon, lat)
    lon_2d[lon_2d > 180] = lon_2d[lon_2d > 180] - 360
    return ds, ds1, lon_range, lat_range, lon, lat, lon_2d, lat_2d

def process_hour(ds, ds1, lon_range, lat_range, lon, lat, lon_2d, lat_2d, time, year, month, day, hour):
    ds_time = f'{year}-{month}-{day}T{hour}'
    wind_shear(ds, lon_range, lat_range, lon_2d, lat_2d, time, ds_time)
    draw_fet(ds, lon_range, lat_range, lon, lat, lon_2d, lat_2d, time, ds_time)
    draw_vert(ds, lon_range, lat_range, lon, lat, lon_2d, lat_2d, time, ds_time)
    draw_vf(ds, lon_range, lat_range, lon, lat, lon_2d, lat_2d, time, ds_time)
    draw_vort(ds, lon_range, lat_range, lon, lat, lon_2d, lat_2d, time, ds_time)
    draw_w(ds, lon_range, lat_range, lon, lat, lon_2d, lat_2d, time, ds_time)
    draw_index(ds1, lon_range, lat_range, lon_2d, lat_2d, time, ds_time)

def process_day(time, year, month, day):
    ds, ds1, lon_range, lat_range, lon, lat, lon_2d, lat_2d = load_data(time)
    hours = range(24)
    Parallel(n_jobs=-1)(
        delayed(process_hour)(ds, ds1, lon_range, lat_range, lon, lat, lon_2d, lat_2d, time, year, month, day, hour)
        for hour in hours
    )

if __name__ == '__main__':
    time = '20220302'
    year, month, day = time[:4], time[4:6], time[6:]
    process_day(time, year, month, day)

其中,load_data函数用于加载数据和处理经纬度数据;process_hour函数用于处理每小时的数据;process_day函数用于处理一天的数据,其中使用joblib.Parallel并行处理24个小时的数据;最后,通过__name__ == 'main'判断是否为主程序,并在主程序中指定处理的日期。

回答不易,还请一定采纳哦!!!

ds1 = xr.open_dataset(f"d:/history_weather/{time}/CDS{time}ts-s.nc")
ds = xr.open_dataset(f"d:/history_weather/{time}/CDS{time}ts-h.nc")
lon = ds1['longitude'].values #读取经度
lat = ds1['latitude'].values #读取纬度
lon_range = lon[(lon>117) & (lon<124)]
lat_range = lat[(lat>24) & (lat<33)]
lons,lats=np.meshgrid(lon_range,lat_range)#网格化
lon_2d, lat_2d = np.meshgrid(lon, lat)
lon_2d[lon_2d > 180] -= 360

for hour in hours:
    ds_time = f"{year}-{month}-{day}T{hour}"
    wind_shear(ds, lon_range, lat_range, lons, lats, time, ds_time)
    draw_fet(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_vert(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_vf(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_vort(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_w(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_index(ds1, lon_range, lat_range, lons, lats, time, ds_time)

上述代码主要的优化包括:

使用了 f-string 格式化字符串,这种方式比使用字符串拼接更快更简单。
直接使用 values 属性获取经度和纬度数据,避免每次访问时都进行数据类型转换。
将重复的计算(如网格化经度和纬度数据)提取到循环外部,避免每次循环都进行计算。
将相同的循环体代码整合到同一个循环中,避免重复计算。
这些优化可能会略微提高代码的运行速度。当然,具体的优化策略还要根据具体情况进行调整,才能达到最佳效果。

参考GPT和自己的思路,可以将重复的代码块进行封装,减少代码冗余。可以使用函数来代替重复的代码块。例如,将draw_fet、draw_vert、draw_vf、draw_vort、draw_w和draw_index的代码块合并为一个函数。同时,使用多线程或异步操作可以提高代码运行速度。具体实现方式可以参考Python的concurrent.futures模块。

下面是一个可能的改进示例:

import concurrent.futures

def process_ds(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time):
    wind_shear(ds, lon_range, lat_range, lons, lats, time, ds_time)
    draw_features(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
    draw_all(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)

def process_all(ds, lon_range, lat_range, lon, lat, lons, lats, time, hours):
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = []
        for hour in hours:
            ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)
            futures.append(executor.submit(process_ds, ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time))
        for future in concurrent.futures.as_completed(futures):
            future.result()

ds1 = xr.open_dataset('d:/history_weather/%s'% (time)+'/CDS%s'% (time)+'ts-s.nc')
ds = xr.open_dataset('d:/history_weather/%s'% (time)+'/CDS%s'% (time)+'ts-h.nc')
lon = ds1['longitude']#读取经度
lat = ds1['latitude']#读取纬度   
lon_range = lon[(lon>117) & (lon<124)]
lat_range = lat[(lat>24) & (lat<33)]
lons,lats=np.meshgrid(lon_range,lat_range)#网格化
lon_2d, lat_2d = np.meshgrid(lon, lat)
lon_2d[lon_2d > 180] = lon_2d[lon_2d > 180] - 360

hours = range(24)
process_all(ds, lon_range, lat_range, lon, lat, lons, lats, time, hours)


注意:这里的示例代码仅供参考,具体的实现方式还需要根据具体的需求和数据进行调整。