Думаю, проще всего конкретизировать мою проблему, обобщенный случай объяснить сложно.
Скажем, у меня есть матрица
a with dimensions NxMxT,
где можно думать о T как о временном измерении (чтобы упростить вопрос). Пусть (n,m) будут индексами через NxM. Я мог бы назвать (n,m) идентификатором пространства состояний. Затем мне нужно найти эквивалент python/scipy для
for each (n,m):
find a*(n,m) = min(a(n,m,:) s.t. a*(n,m) > a(n,m,T)
То есть найти наименьшее значение в пространстве состояний, которое все еще выше, чем последнее (среди измерения времени) наблюдение - для всего пространства состояний.
Моя первая попытка состояла в том, чтобы сначала решить внутреннюю проблему (найти a, которое выше, чем [..., -1]):
aHigherThanLast = a[ a > a[...,-1][...,newaxis] ]
И затем я хотел найти наименьшее среди всех этих для каждого (n, m). К сожалению, aHigherThanLast теперь содержит одномерный массив всех этих значений, поэтому у меня больше нет соответствия (n,m). Что было бы лучшим подходом к этому?
В качестве дополнительной проблемы: пространство состояний является переменным, оно также может иметь 3 или более измерений (NxMxKx...), и я не могу жестко закодировать это. Так что любой вид
for (n,m,t) in nditer(a):
не осуществимо.
Большое спасибо!
/редактировать:
a = array([[[[[[[[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.]]]],
[[[[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.]]]]],
[[[[[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.]]]],
[[[[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.],
[ 0., 2., 1.]]]]]]]])
# a.shape = (1L, 1L, 2L, 2L, 1L, 1L, 10L, 3L). so in this case, T = 3.
# expected output would be the sort of
# b.shape = (1L, 1L, 2L, 2L, 1L, 1L, 10L), which solves
b[a,b,c,d,e,f,g] > a[a,b,c,d,e,f,g,-1] (b больше, чем самое новое наблюдение)
Нет элемента i в a, который удовлетворяет обоим
-- a[a,b,c,d,e,f,g,t] > a[a,b,c,d,e,f,g,-1]
-- a[a,b,c,d,e,f,g,t] ‹ b[a,b,c,d,e,f,g] (b - наименьший элемент, который старше самого нового наблюдения )
Итак, учитывая, что предыдущий массив представляет собой простой стек, если [0,2,1] по последнему наблюдению, я ожидал бы
b = ones((1,1,2,2,1,1,10))*2
однако - если бы среди некоторых (a,b,c,d,e,f,g) было не только значение либо {0,1,2}, но и {3}, то я бы все равно хотел 2 (поскольку это меньшее из i = {2,3}, которое удовлетворяет i > 1. - если среди некоторых (a,b,c,d,e,f,g) было только значение {0,1 ,3}, я бы хотел 3, так как i = 3 будет наименьшим числом, удовлетворяющим i > 1.
Надеюсь, немного прояснилось?
/edit2:
Очень ценю ответ, он работает. Как бы я его настроил, если бы хотел наоборот, т.е. самый большой среди тех, что поменьше? Я не пытался пройти через эту сложную логику индексации, поэтому моя (слабая) попытка изменить только первые три строки не увенчалась успехом:
b = sort(a[...,:-1], axis=-1)
b = b[...,::-1]
mask = b < a[..., -1:]
index = argmax(mask, axis=-1)
indices = tuple([arange(j) for j in a.shape[:-1]])
indices = meshgrid(*indices, indexing='ij', sparse=True)
indices.append(index)
indices = tuple(indices)
a[indices]
Кроме того, a[...,::-1][indices], моя вторая попытка тоже не увенчалась успехом.
end_slice = a[..., -1]; b = np.sort(a, axis=-1); b >= end_slice[..., None]; indices = np.argmax(b >= end_slice[..., None], axis=-1)
(точки с запятой там, где у нас должны быть новые строки...) - person YXD   schedule 12.11.2013