我需要将尺寸为 (12,1800,3600)(时间经纬度)的精细矩阵变量(称为“fine_var”)重新网格化为尺寸为(12,180,360)(时间、纬度、经度)的粗矩阵变量(称为“coarse_var”) ),不对变量进行插值,而是将细矩阵每个单元对粗矩阵单元的贡献求和。
为此,我使用 python 创建了一个循环:
for ii in range(len(ds.fine_var[0,:,0])-1):
for jj in range(len(ds.fine_var[0,0,:])-1):
coarse_var[:,int(ii/10),int(jj/10)]+=ds.fine_var[:,ii,jj]
但是,这个循环太繁重,无法计算,我想知道Python中是否有一种轻量级方法来创建粗网格而不需要对变量进行插值。
有人可以提供帮助吗?
非常感谢任何帮助!
您不是在这里进行插值,而是对精细采样的数据进行平均以产生较低分辨率的粗略版本。插值意味着使用现有数据集来估计更精细网格上的值。
我实际上并不知道您选择的语言中数组的确切布局,但我怀疑您对数组求和的顺序可能是页面错误和缓存未命中的最坏情况。爱喔
for ii in range(len(ds.fine_var[0,:,0])-1):
for jj in range(len(ds_disk.fine_var[0,0,:])-1):
应该换成
for jj in range(len(ds_disk.fine_var[0,0,:])-1):
for ii in range(len(ds.fine_var[0,:,0])-1):
然后它的运行速度可能足以满足您的目的。先试试这个!
您还应该意识到除法(除了 2^n 之外)和少数特殊情况是昂贵的缓慢操作,并且延迟很高。最好在快速代码中避免。同样,对于数组写入访问,您的简单循环代码会执行其中 100 次,而实际上只需要一次。
我无法用 Python 编写它,但我可以建议伪代码,该伪代码将使此代码更快地将精细数据集平均到较粗的网格并缓存在本地。
我在这里假设数组布局在内存中看起来像这样:
x[0,0] x[0,1] x[0,2] ...x[0,NX-1] x[1,0] x[1,1] ... x[1,NX-1] x[2,0]... ...x[NY-1,NX-1]
遵循索引命名约定:
for jj = 0 to (NY-1)/10
jj10 = 10*jj
for ii = 0 to (NX-1)/10
ii10 = 10*ii
sum = 0;
for j = jj10 to jj10+9
for i = ii10 to ii10+9
sum += fine_var[i,jj10];
next i
next j
coarse_var[ii,jj] = sum
next ii
next jj
如果您只想执行一次,只需翻转原始代码中 ii,jj 循环的顺序就足够了!练习的目的是在工作正在进行时使所有内容都适合缓存。可能还有进一步的优化,但我希望这会足够快。它避免了大量不必要的数组访问,并将最终总和存储到目标数组中,一次在正确的位置移动一次 10 行的步骤遍历原始数组。
如果你运行一个大数组,索引顺序错误,那么一切都是缓存未命中,并且冰川 s-l--o---w。 PS,您可能还想通过除以 100 对其进行标准化(如果是单位面积则不除)。