Возвращаемое значение самого высокого индекса в массивном трехмерном массиве - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть 3D-массив в numpy, который включает в себя nans.Мне нужно вернуть значение с наибольшей позицией индекса по оси 0.Ответ сводится к двумерному массиву.

Существует множество вопросов о поиске позиции индекса максимального значения вдоль оси ( Как получить индекс максимального элемента в массиве с нулевыми значениями)вдоль одной оси ), но это отличается от того, что мне нужно.

Пример трехмерного массива:

>>> import numpy as np
>>> foo = np.asarray([[[7,4,6],[4,2,11], [7,8,9], [4,8,2]],[[1,2,3],[np.nan,5,8], [np.nan,np.nan,10], [np.nan,np.nan,7]]])
>>> foo
array([[[  7.,   4.,   6.],
        [  4.,   2.,  11.],
        [  7.,   8.,   9.],
        [  4.,   8.,   2.]],

       [[  1.,   2.,   3.],
        [ nan,   5.,   8.],
        [ nan,  nan,  10.],
        [ nan,  nan,   7.]]])

Я думал, что я приближался, используя np.where, но он возвращает все элементы, которые не являются nan.Не совсем то, что мне нужно, потому что я хочу массив (4,3).

>>> zoo = foo[np.where(~np.isnan(foo))]
>>> zoo
array([  7.,   4.,   6.,   4.,   2.,  11.,   7.,   8.,   9.,   4.,   8.,
     2.,   1.,   2.,   3.,   5.,   8.,  10.,   7.])

Мне нужен ответ:

>>> ans = np.asarray([[1,2,3], [4,5,8], [7,8,10], [4,8,7]])
>>> ans
array([[ 1,  2,  3],
       [ 4,  5,  8],
       [ 7,  8, 10],
       [ 4,  8,  7]])

РЕДАКТИРОВАТЬ: я отредактировал пример массива foo, чтобы задать вопросболее ясно.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Векторное решение, только с индексами:

def last_non_nan(foo):
    i = np.isnan(foo)[::-1].argmin(0)
    j,k = np.indices(foo[0].shape)
    return foo[-i-1,j,k]

i содержит индекс первого не числового числа в перевернутой «строке».поэтому -i-1 - это его индекс по прямой линии.

>>> last_non_nan(foo):
  [[  1.,   2.,   3.],
   [  4.,   5.,   8.],
   [  7.,   8.,  10.],
   [  4.,   8.,   7.]]

Быстрее, чем highest_index:

In [5]%timeit last_non_nan(foo)
133 µs ± 29.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [6]: %timeit np.apply_along_axis(highest_index,0,foo)
667 µs ± 90 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

до 150x (40 мс против 6 с) быстрее для массива (10 400 400) с 90% nans.

Это в основном потому, что last_non_nan просто извлекает последнее значение non-nan в каждой строке, когда highest_index вычисляет индекс и извлекает все значения non-nan.

0 голосов
/ 12 декабря 2018

Вы можете использовать np.nanmax:

>>> np.nanmax(foo, axis=0)
array([[ 7.,  4.,  6.],
       [ 4.,  5., 11.],
       [ 7.,  8., 10.],
       [ 4.,  8.,  7.]])

Функция np.nanmax возвращает максимум массива или максимум вдоль оси, игнорируя любые значения NaN.

РЕДАКТИРОВАТЬ

Как вы правильно указали в своем комментарии, вам нужно значение с максимальным индексом, а код выше не возвращает его.

Вместо этого вы можете использовать apply-along-axis:

>>> def highest_index(a):
...     return a[~np.isnan(a)][-1] # return non-nan value at highest index

>>> np.apply_along_axis(highest_index, 0, foo)
array([[ 1.  2.  3.]
       [ 4.  5.  8.]
       [ 7.  8. 10.]
       [ 4.  8.  7.]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...