考虑一个矩阵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}},
效率是关键。
答案 0 :(得分:1)
根据您的原始问题条件,重新创建如下,修改为A
是Z
的副本:
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
将传播到最终数组。