Python a";ij“;网格网格和长网格网格

Python a";ij“;网格网格和长网格网格,python,numpy,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 我需要一个代码来将该对象转换为形状为(x,3)的对象Z2。Z2中的每一行对应于Z2中的一个元素I:(aGrid[a[I]]、mGrid[m[I]]、eGr

考虑一个矩阵
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

我需要一个代码来将该对象转换为形状为(x,3)的对象
Z2
Z2
中的每一行对应于
Z2
中的一个元素
I
(aGrid[a[I]]、mGrid[m[I]]、eGrid[e[I]

通过一些计算,我得到了一个矩阵
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)
,则
V4
中所有行的
V
处的
V
值等于v1,等等


效率是关键

因此Z与A、M、E的形状相同;在这种情况下,Z2是形状(Z.ravel(),len(grids))=(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
将传播到最终数组。

根据原始问题条件,按如下方式重新创建,修改后的
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
#数据点
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的情况下也可以工作,但在这种情况下,它将不包括输入数组的相应列中不存在的任何坐标。

Z=A;Z[Z>3]=np.NaN;这里您还可以在A.Good find中设置值。在这个简单的示例中,这是真的,在我的实际代码中,我有类似于
Z=A+M**2….
。无论如何,调用A、M、E只是为了获得
Z
的正确形状并删除无效状态,所以这并不太重要。因为您从Z2中删除了元素,所以您不能毫不含糊地重新创建Z。您将获得哪些信息?网格中阵列的数量和形状?我想知道您为什么需要以这种方式前后移动。好吧,实际上,我不想转换回
Z2
。我有一个形状为Z2的计算结果,但值不同,我想返回到
ij
-网格上的原始格式。我可以保存
Z2
的中间版本(带有
NaN
标记的中间版本,在删除它们之前)-也许这会有帮助,因为这样你就有了
NaN
的位置,也就是说,最终的
Z2
格式的数据缺少项。否则,你还需要什么?目前你的问题中仍然存在矛盾——Z2和Z3在你的代码中只有3列,而在文本中你将它们定义为第四列(前三列指定的网格坐标处的实际值)。我一直没有编辑您的答案,很抱歉!现在我正试图了解发生了什么。我完全按照您的粘贴进行操作,但在以
新数组开头的行中得到
键错误:100.0
[tuple…
.Oops.请查看我的最新编辑-示例现在可以运行了。(将网格坐标映射到N-D数组索引的函数的映射方向错误。)
np.all(Z[~np.isnan(Z)] == V4_orig_form[~np.isnan(V4_orig_form)])