Закажите мин над ndarrays, сохраняя информацию об исходных индексах - PullRequest
0 голосов
/ 19 сентября 2018

Рассмотрим вариант numpy.ndarray D1 с формой (10,N,M).
Я бы хотел построить новый ndarray O1 с формой (N*M,3).так, что:

  • каждый элемент является триплетом, который идентифицирует индекс элемента по D1
  • , индексы сортируются согласно их значению соответствующих полей в D1
  • для каждого 0≤i≤N, 0≤j≤M рассматривается только минимальный элемент из 10 измерений.

Давайте рассмотрим небольшой пример с 2 вместо 10 и текущий подход, который частично достигает моей цели:

>>> d1 = np.random.randint(20, size=2*3*3).reshape(2,3,3)

array([[[ 2,  6, 18],
        [18, 18, 10],
        [ 2,  3,  1]],

        [[11,  3, 14],
        [12, 14, 18],
        [ 6,  8, 19]]])

>>> d2 = np.amin(d1, axis=0)

array([[ 2,  3, 14],
       [12, 14, 10],
       [ 2,  3,  1]])

>>> o1 = np.dstack(np.unravel_index(np.argsort(d2.ravel()), d2.shape))

array([[[2, 2],
        [0, 0],
        [2, 0],
        [0, 1],
        [2, 1],
        [1, 2],
        [1, 0],
        [0, 2],
        [1, 1]]])

Таким образом, я получаю минимальные индексы для элементов по отношению к измерению 2, но я теряю информацию о начальных индексах в D1.

Ожидаемый результат должен быть в этом случае:

array([[[0, 2, 2],
        [0, 0, 0],
        [0, 2, 0],
        [1, 0, 1],
        [0, 2, 1],
        [0, 1, 2],
        [1, 1, 0],
        [1, 0, 2],
        [1, 1, 1]]])

1 Ответ

0 голосов
/ 19 сентября 2018

Структурированный массив - это удобный способ одновременно работать с индексами и минимальными значениями:

M, N = d1.shape[1:]
mi, ni = np.ogrid[:M, :N]
data = np.empty((M, N), [('coords', np.intp, 3), ('min', d1.dtype)])
data['coords'][..., 0] = mi
data['coords'][..., 1] = ni
data['coords'][..., 2] = np.argmin(d1, axis=0)
data['min'] = np.min(d1, axis=0)

data = data.ravel()  # collapse (M, N) to (M*N,)
data_sorted = data[np.argsort(data['min'])]
o1 = data_sorted['coords']

Но вы также можете легко получить его из своего кода:

d2 = np.min(d1, axis=0)
arg_d2 = np.argmin(d1, axis=0)
order = np.argsort(d2.ravel())
mi, ni = np.unravel_index(order, d2.shape)
o1 = np.stack((mi, ni, arg_d2.ravel()[order]), axis=-1)  # dstack but faster
...