这是我的问题:我使用numpy和python操作432*46*136*136
表示包含在numpy数组中的time*(space)
的网格。我有一个数组alt
,它包含网格点的高度,另一个数组temp
存储网格点的温度。
比较存在问题:如果T1
和T2
是两个结果,则T1[t0,z0,x0,y0]
和T2[t0,z0,x0,y0]
代表H1[t0,z0,x0,y0]
和{{1}的温度分别是米。但我想比较同一高度的点的温度,而不是相同的网格点。
因此我想修改矩阵的z轴来表示高度而不是网格点。我创建了一个函数H2[t0,z0,x0,y0]
,它将每个高度的-20到200之间的数字归属。这是我的代码:
conv(alt[t,z,x,y])
但这需要花费太多时间,我无法解决这个问题。我尝试用numpy的通用函数编写它:
def interpolation_extended(self,temp,alt):
[t,z,x,y]=temp.shape
new=np.zeros([t,220,x,y])
for l in range(0,t):
for j in range(0,z):
for lat in range(0,x):
for lon in range(0,y):
new[l,conv(alt[l,j,lat,lon]),lat,lon]=temp[l,j,lat,lon]
return new
但这不起作用。你有没有想过在没有使用4个嵌套循环的情况下在python / numpy中这样做?
谢谢
答案 0 :(得分:3)
我无法真正尝试代码,因为我没有你的矩阵,但是这样的事情应该可以胜任。
首先,不要将conv
声明为函数,而是获取所有数据的整体高度预测:
conv = np.round(alt / 500.).astype(int)
使用np.round
,numpys版本的round,它通过向量化C中的操作来舍入矩阵的所有元素,因此,您可以非常快速地获得新数组(以C速度)。通过将所有数组移动到最小值(在您的情况下为-20),以下行将高度与0开始对齐:
conv -= conv.min()
上面的行会将您的高度矩阵从[-20,200]变换为[0,220](更适合索引)。
通过这种方式,可以通过获得多维索引轻松完成插值:
t, z, y, x = np.indices(temp.shape)
上面的向量包含索引原始矩阵所需的所有索引。然后,您可以通过执行以下操作来创建新矩阵:
new_matrix[t, conv[t, z, y, x], y, x] = temp[t, z, y, x]
根本没有任何循环。
让我知道它是否有效。它可能会给你一些错误,因为我很难在没有数据的情况下测试它,但它应该可以完成这项工作。
以下玩具示例正常:
A = np.random.randn(3,4,5) # Random 3x4x5 matrix -- your temp matrix
B = np.random.randint(0, 10, 3*4*5).reshape(3,4,5) # your conv matrix with altitudes from 0 to 9
C = np.zeros((3,10,5)) # your new matrix
z, y, x = np.indices(A.shape)
C[z, B[z, y, x], x] = A[z, y, x]
C
按海拔高度显示结果。