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)
此段代码,是运用在main函数中的,每一个for对应的函数,运行时都需要读取一次数据,然后计算后再绘图。经过测试,单独的7个for循环,比一个for带上所有函数能节省一半的时间。
个人理解:以wind_shear为例,单独的for循环中,计算一次后再按不同hour绘图7次即可,而整体的for循环需要7次计算再7次绘图。
所以有没有什么方式使得更加简洁,同时提高运行速度。
可以考虑使用并行计算来加快代码运行速度。使用multiprocessing库可以在多个进程中同时运行这些函数
参考GPT和自己的思路,您可以尝试以下优化方式:
缓存重复读取的数据,避免重复读取。比如将 ds1 和 ds 存储在变量中,在需要时直接使用变量即可。
对于需要循环的数据,可以考虑使用 numpy 的数组计算,避免使用循环,提高代码运行速度。
使用并行计算库,如 multiprocessing、joblib 等,将代码运行分配到多个 CPU 核心上并行计算。
例如,对于您的代码,可以将数据读取和网格化部分提取出来,避免每次循环都读取和网格化。同时,对于循环部分,可以使用 numpy 的数组计算和 joblib 库的并行计算来提高速度,示例代码如下:
import numpy as np
from joblib import Parallel, delayed
# 读取数据
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
# 并行计算绘图
def compute_draw(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time, func):
data = func(ds, lon_range, lat_range, lon, lat, lons, lats, time, ds_time)
draw(data)
Parallel(n_jobs=-1)(
delayed(compute_draw)(
ds, lon_range, lat_range, lon, lat, lons, lats, time, '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour), func)
for func in [wind_shear, draw_fet, draw_vert, draw_vf, draw_vort, draw_w, draw_index]
for hour in hours
)
在以上示例代码中,使用了并行计算库 joblib 来实现对每个函数的并行运行,通过设置 n_jobs=-1 可以让程序自动利用所有可用的 CPU 核心进行计算。同时,将循环部分移动到 Parallel 函数内部,在循环内部计算和绘图。通过这种方式,可以提高代码的运行效率,减少重复计算。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,我们可以将读取数据的代码放在一个for循环外面,这样就可以只读取一次数据,而不是每个子函数都要读取一次:
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)
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)
此外,我们可以使用numba库加速代码运行。
from numba import jit
@jit(nopython=True)
def wind_shear_numba(u10, v10, u500, v500, lon_range, lat_range, lons, lats):
# 将wind_shear函数中的相关内容放到一个用numba装饰的函数中,
# 并将函数中使用的循环全部换成numba支持的循环形式(例如prange等)
# 具体要根据函数中的实现细节进行修改
pass
for hour in hours:
ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(hour)
u10 = ds.u10.sel(time=ds_time).sel(longitude=lon_range).sel(latitude=lat_range).values
v10 = ds.v10.sel(time=ds_time).sel(longitude=lon_range).sel(latitude=lat_range).values
u500 = ds['u'].sel(time=ds_time, level=500).sel(longitude=lon_range).sel(latitude=lat_range).values
v500 = ds['v'].sel(time=ds_time, level=500).sel(longitude=lon_range).sel(latitude=lat_range).values
# 直接调用使用numba装饰的函数
wind_shear_numba(u10, v10, u500, v500, lon_range, lat_range, lons, lats)
需要注意的是,使用numba需要有一些限制,例如函数中的循环不能是动态(Python风格的)循环,需要使用静态循环,同时需要注意一些数据类型的使用等等。因此具体实现需要考虑具体的函数实现细节。
如果我的回答解决了您的问题,请采纳!
“Devil组”引证GPT后的撰写:
把for循环的函数的计算和绘图整合到一个for循环中
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)
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)
该回答引用ChatGPT
有几个技巧可以帮助提高 Python 计算绘图代码的运行速度:
1、避免重复读取数据
在循环中多次读取同一数据集会浪费时间和内存。可以在循环外读取一次数据,然后将数据传递给每个函数。
2、合并多个循环
可以将多个循环合并成一个,这样可以避免重复读取数据并提高代码的效率。
3、并行化
使用并行计算可以将计算任务分配给多个处理器或核心,从而提高代码的运行速度。
下面是一个修改后的示例代码,其中采用了上述技巧:
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
def draw_all(ds, ds1, lon_range, lat_range, lon, lat, lons, lats, time, hours):
from concurrent.futures import ThreadPoolExecutor
def draw_hour(hour):
ds_time = '%s' % (year) + '-' + '%s' % (month) + '-' + '%s' % (day) + 'T' + '%s' % (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)
with ThreadPoolExecutor() as executor:
executor.map(draw_hour, hours)
draw_all(ds, ds1, lon_range, lat_range, lon, lat, lons, lats, time, hours)
参考chatGPT的内容和自己的思路,以减少重复计算,从而提高代码的运行速度。以下是优化建议:
1.将读取经纬度数据和网格化操作移至循环外部。这些操作只需要在程序开始时执行一次,而不是每个循环内部都执行一次。
2.将不需要修改的变量(如lon和lat)定义为常量,以避免每次循环都重新定义变量。
3.将多个循环合并为一个循环,从而减少循环的数量。
4.使用NumPy的向量化运算来代替循环,因为NumPy的向量化运算在处理大量数据时比循环更高效。
5.尝试使用并行计算(例如使用multiprocessing库)来加速程序。
下面是优化后的代码:
import multiprocessing as mp
# 读取经度和纬度数据
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'].values # 读取经度
lat = ds1['latitude'].values # 读取纬度
lon[lon > 180] -= 360 # 将经度从0-360转换为-180-180
# 定义常量
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)
def process_hour(hour):
ds_time = '%s'%(year)+'-'+'%s'%(month)+'-'+'%s'%(day)+'T'+'%s'%(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)
if __name__ == '__main__':
# 将循环合并为一个循环,并使用并行计算
with mp.Pool() as pool:
pool.map(process_hour, hours)
回答不易,还请采纳!!!