简体   繁体   English

Usind 3D数组索引4D数组

[英]Usind 3d array to index 4d array

I have a 4d-xarray with dimensions I[t, z, y, x] and a 3d-xarray with dimensions Z[t, y, x] . 我有一个尺寸为I[t, z, y, x]的4d-xarray和一个尺寸为Z[t, y, x]的3d-xarray。 Z are the indices I need for dimension z in I . Z是我需要在尺寸Z指数I Now I want to get the values I[t, Z[t,y,x], y, x] and write them into a new xarray of size O[t, y, x] . 现在,我想获取值I[t, Z[t,y,x], y, x]并将它们写入大小为O[t, y, x]的新xarray中。

In principal I solved the problem by using for-loops, but that is way too slow (a lot and large arrays). 原则上,我通过使用for循环解决了这个问题,但这太慢了(很多数组)。 Is there a way to do this without for-loops? 有没有办法没有for循环?

Example code doing what I want but to slow: 示例代码做我想要的但要慢:

def get_field_at_levels(array, levels):
    shape = array.shape
    array_out = np.zeros_like(levels)
    for t in range(shape[0]):
        for x in range(shape[2]):
            for y in range(shape[3]):
                if np.isnan(levels[t, x, y]):
                    array_out[t, x, y]==float('nan')
                else:
                    array_out[t, x, y] = array[t, int(levels[t, x, y]), x, y]
    return array_out

I converted all my xarrays to numpy.arrays using numpy.asarray. 我使用numpy.asarray将所有xarrays转换为numpy.arrays。 Now the program is fast enough using loops. 现在程序使用循环已经足够快了。 Below an example script using random numbers. 下面是使用随机数的示例脚本。 In my actual data I have indices out of range (-1). 在我的实际数据中,我的索引超出范围(-1)。 In this case I want NaN as result. 在这种情况下,我想要NaN作为结果。

import numpy as np
import time

tsize = 1
xsize = 40
ysize = 240
zsize = 260

def val_at_lev(data, Ind):
    sh=data.shape
    data2=np.empty([sh[0],sh[1]+1,sh[2],sh[3]])
    data2[:,0:sh[1],:,:]=data
    data2[:,sh[1],:,:]='nan'
    out=np.asarray(np.zeros_like(Ind))
    erg=np.asarray([data2[t,Ind[t,0,j,k],j,k] for t in range(sh[0]) for j in range(sh[2]) for k in range(sh[3])])
    out = erg.reshape(tsize,1,ysize,zsize)
    return out

# Main program
Ind=np.random.randint(-1,xsize,[tsize,1,ysize,zsize])
data=np.random.uniform(0,100,[tsize,xsize,ysize,zsize])
start_time = time.time()
erg=val_at_lev(data,Ind)
print("--- %s seconds ---" % (time.time() - start_time))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM