“ij”网格网格与长网格网格之间的对应关系

时间:2014-07-27 13:04:38

标签: python numpy

考虑一个矩阵Z,其中包含z = z(a,m,e)的基于网格的结果。 Z的形状为(len(aGrid), len(mGrid), len(eGrid))Z[0,1,2]包含z(a=aGrid[0], m=mGrid[1], e=eGrid[2])。但是,我们可能已从对象中删除了状态空间中的一些元素(例如,简单,(a,m,e : a > 3)。假设有效状态空间的大小为x

have been suggested将此对象转换为形状Z2的对象(x, 3)的代码。 Z2中的每一行都对应i Z2中的元素(aGrid[a[i]], mGrid[m[i]], eGrid[e[i]])

# first create Z, a mesh grid based matrix that has some invalid states (we set them to NaN)
aGrid = np.arange(0, 10, dtype=float)
mGrid = np.arange(100, 110, dtype=float)
eGrid = np.arange(1000, 1200, dtype=float)
A,M,E = np.meshgrid(aGrid, mGrid, eGrid, indexing='ij')
Z = A
Z[Z > 3] = np.NaN #remove some states from being "allowed"

# now, translate them from shape (len(aGrid), len(mGrid), len(eGrid)) to 
grids = [A,M,E]
grid_bc = np.broadcast_arrays(*grids)
Z2 = np.column_stack([g.ravel() for g in grid_bc])
Z2[np.isnan(Z.ravel())] = np.nan
Z3 = Z2[~np.isnan(Z2)]

通过一些计算,我得到一个矩阵V4,其形状为Z3但包含 4 列。

我得到了

  • Z2(如上所述)
  • Z3(如上所述)
  • V4这是一种矩阵形状(Z3.shape[0], Z3.shape[1]+1):附加了一列
  • (如有必要,我仍然可以访问网格A,M,E

我需要重新创建

  • V,这是包含V4的值(最后一列)的矩阵,但会转换回Z1的形状。

也就是说,如果V4中有一行读取(aGrid[0], mGrid[1], eGrid[2], v1),那么V的{​​{1}}值就等于V[0,1,2] = v1中的所有行1}},

效率是关键

2 个答案:

答案 0 :(得分:1)

根据您的原始问题条件,重新创建如下,修改为AZ副本

aGrid = np.arange(0, 10, dtype=float)
mGrid = np.arange(100, 110, dtype=float)
eGrid = np.arange(1000, 1200, dtype=float)
A,M,E = np.meshgrid(aGrid, mGrid, eGrid, indexing='ij')
Z = A.copy()
Z[Z > 3] = np.NaN 

grids = [A,M,E]
grid_bc = np.broadcast_arrays(*grids)
Z2 = np.column_stack([g.ravel() for g in grid_bc])
Z2[np.isnan(Z.ravel())] = np.nan
Z3 = Z2[~np.isnan(Z2)]

可以如下定义函数,以从稀疏的2D # data points x # dims + 1矩阵重建密集的N-D矩阵。函数的第一个参数是前面提到的2D矩阵,最后(可选)参数是每个维度的网格索引:

import numpy as np
def map_array_to_index(uniq_arr):
    return np.vectorize(dict(map(reversed, enumerate(uniq_arr))).__getitem__)

def recreate(arr, *coord_arrays):
    if len(coord_arrays) != arr.shape[1] - 1:
      coord_arrays = map(np.unique, arr.T[0:-1])
    lookups = map(map_array_to_index, coord_arrays)
    new_array = np.nan * np.ones(map(len, coord_arrays))
    new_array[tuple(l(c) for c, l in zip(arr.T[0:-1], lookups))] = arr[:, -1]
    new_grids = np.meshgrid(*coord_arrays, indexing='ij')
    return new_array, new_grids

给定2D矩阵V4,上面定义了从Z派生的值,

V4 = np.column_stack([g.ravel() for g in grid_bc] + [Z.ravel()])

可以按如下方式重新创建Z:

V4_orig_form, V4_grids = recreate(V4, aGrid, mGrid, eGrid)

所有非NaN值都正确地测试相等性:

np.all(Z[~np.isnan(Z)] == V4_orig_form[~np.isnan(V4_orig_form)])

该函数也可以在没有传入aGrid,mGrid,eGrid的情况下工作,但在这种情况下,它不会包含输入数组的相应列中不存在的任何坐标。

答案 1 :(得分:0)

所以Z的形状与A,M,E相同;在这种情况下,Z2是形状(Z.ravel(),len(网格))=(10x10x200,3)(如果你没有过滤出NaN元素)。 这是您根据Z2

的值重新创建网格的方法
grids = Z2.T
A,M,E = [g.reshape(A.shape) for g in grids]
Z = A # or whatever other calculation you need here

您唯一需要的是您想要回归的形状。 NaN将传播到最终数组。