【发布时间】:2026-01-27 19:55:01
【问题描述】:
我正在编写循环多个 netcdf 文件(大 ~28G)的代码。 netcdf 文件在整个域中具有多个 4D 变量[时间、东西、南北、高度]。目标是遍历这些文件并遍历域中所有这些变量的每个位置,并提取某些变量以存储到一个大数组中。当文件丢失或不完整时,我用 99.99 填充这些值。现在我只是通过循环超过 2 个每日 netcdf 文件进行测试,但由于某种原因,它需要永远(约 14 小时)。我不确定是否有办法优化这段代码。我不认为 python 应该花这么长时间来完成这项任务,但也许这是 python 或我的代码的问题。以下是我的代码,希望它是可读的,非常感谢任何关于如何使其更快的建议:
#Domain to loop over
k_space = np.arange(0,37)
j_space = np.arange(80,170)
i_space = np.arange(200,307)
predictors_wrf=[]
names_wrf=[]
counter = 0
cdate = start_date
while cdate <= end_date:
if cdate.month not in month_keep:
cdate+=inc
continue
yy = cdate.strftime('%Y')
mm = cdate.strftime('%m')
dd = cdate.strftime('%d')
filename = wrf_path+'\wrfoutRED_d01_'+yy+'-'+mm+'-'+dd+'_'+hour_str+'_00_00'
for i in i_space:
for j in j_space:
for k in k_space:
if os.path.isfile(filename):
f = nc.Dataset(filename,'r')
times = f.variables['Times'][1:]
num_lines = times.shape[0]
if num_lines == 144:
u = f.variables['U'][1:,k,j,i]
v = f.variables['V'][1:,k,j,i]
wspd = np.sqrt(u**2.+v**2.)
w = f.variables['W'][1:,k,j,i]
p = f.variables['P'][1:,k,j,i]
t = f.variables['T'][1:,k,j,i]
if num_lines < 144:
print "partial files for WRF: "+ filename
u = np.ones((144,))*99.99
v = np.ones((144,))*99.99
wspd = np.ones((144,))*99.99
w = np.ones((144,))*99.99
p = np.ones((144,))*99.99
t = np.ones((144,))*99.99
else:
u = np.ones((144,))*99.99
v = np.ones((144,))*99.99
wspd = np.ones((144,))*99.99
w = np.ones((144,))*99.99
p = np.ones((144,))*99.99
t = np.ones((144,))*99.99
counter=counter+1
predictors_wrf.append(u)
predictors_wrf.append(v)
predictors_wrf.append(wspd)
predictors_wrf.append(w)
predictors_wrf.append(p)
predictors_wrf.append(t)
u_names = 'u_'+str(k)+'_'+str(j)+'_'+str(i)
v_names = 'v_'+str(k)+'_'+str(j)+'_'+str(i)
wspd_names = 'wspd_'+str(k)+'_'+str(j)+'_'+str(i)
w_names = 'w_'+str(k)+'_'+str(j)+'_'+str(i)
p_names = 'p_'+str(k)+'_'+str(j)+'_'+str(i)
t_names = 't_'+str(k)+'_'+str(j)+'_'+str(i)
names_wrf.append(u_names)
names_wrf.append(v_names)
names_wrf.append(wspd_names)
names_wrf.append(w_names)
names_wrf.append(p_names)
names_wrf.append(t_names)
cdate+=inc
【问题讨论】:
-
您可以使用多处理同时处理文件。为不同的进程安排 k,j,i 空间,让它们各自完成自己的任务
-
什么是
nc.Dataset?此外,在提高速度之前,您需要知道它为什么慢。您需要分析您的代码并测量。 -
这是我使用 python 读取 netcdf 文件的方式 我在前面的代码中有一个语句,此处未显示:import netCDF4 as nc
-
下面的多核建议会有所帮助。此外,如果您在 iPython notebook 中工作,将其写入从命令行运行的脚本可以极大地加快速度。 28GB 是一个巨大的文件。如果两个文件都在这个大小范围内,并且您有 3 个带条件的循环,那么在单个内核上运行 14 小时并不是不存在的,无论它看起来多么荒谬。 R 比 Python 慢得多,较小的文件需要 8 到 12 次才能通过更少的循环进行排序。只要尽可能保守地处理冗余操作并启动更多内核!
-
您似乎多次浏览文件,{f.variables['Times'][1:]} 浏览文件以搜索这些var。这是针对每个循环完成的。这样做一次,而不是在每个循环中。
标签: python performance loops timing