Рассмотрим матрицу 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.

Мне предложили код для преобразования этого объекта в объект 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 в V[0,1,2] = v1 и т. Д. Для всех строк в V4 ,

Эффективность - ключ к успеху .

2
FooBar 27 Июл 2014 в 17:04

2 ответа

Лучший ответ

Учитывая исходные условия проблемы, воссозданные следующим образом, измененные таким образом, что 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)]

Функция может быть определена следующим образом, чтобы воссоздать плотную N-D матрицу из разреженной 2D-матрицы # data points x # dims + 1. Первым аргументом функции является упомянутая 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
rroowwllaanndd 19 Авг 2014 в 11:12

Итак, 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 будет распространяться на последний массив.

0
mdurant 30 Июл 2014 в 17:52