Как получить наивысший элемент по абсолютной величине в матрице numpy?
Вот что я сейчас делаю, это работает, но это немного громоздко:
x = np.matrix([[1, 1], [2, -3]])
xmax = x.flat[abs(x).argmax()]
Ответы
Ответ 1
Значение, которое вы ищете, должно быть либо x.max()
, либо x.min()
, чтобы вы могли сделать
max(x.min(), x.max(), key=abs)
который похож на решение aestrivex, но, возможно, более читабельным? Обратите внимание, что это вернет минимум в случае, когда x.min()
и x.max()
имеют одинаковое абсолютное значение, например. -5
и 5
. Если у вас есть предпочтение, просто закажите входы на max
соответственно.
Ответ 2
Я искал способ получить подписанные значения максимальных абсолютных значений N-мерного массива вдоль указанной оси, с которыми не справляется ни один из этих ответов. Итак, я собрал функцию для этого. Нет promises, но он работает, насколько я его протестировал:
def maxabs(a, axis=None):
"""Return slice of a, keeping only those values that are furthest away
from 0 along axis"""
maxa = a.max(axis=axis)
mina = a.min(axis=axis)
p = abs(maxa) > abs(mina) # bool, or indices where +ve values win
n = abs(mina) > abs(maxa) # bool, or indices where -ve values win
if axis == None:
if p: return maxa
else: return mina
shape = list(a.shape)
shape.pop(axis)
out = np.zeros(shape, dtype=a.dtype)
out[p] = maxa[p]
out[n] = mina[n]
return out
Ответ 3
ИЗМЕНИТЬ. Мой ответ не по теме, извините. Как отметил Офион, это вернет индекс, а не значение - вы должны использовать flat
с моим "xmax
" (который действительно "xmaxInd
" ), чтобы получить правильное значение. Ergo Я думаю, что ваше решение лучше всего.
После нескольких экспериментов я понял, что вы можете просто сделать это:
x = np.matrix([[1,1], [2,-3]])
absX = abs(x)
xmax = argmax(absX)
Кажется, что numpy позволяет взять abs
, а также argmax
матрицы. Как удобно!
timeit
проверяет:
def meth1():
x = np.matrix([[1,1],[2,-3]])
xmax = x.flat[abs(x).argmax()]
def meth2():
x = np.matrix([[1,1],[2,-3]])
xmax = argmax(abs(x))
t1 = timeit.Timer("meth1()","from __main__ import meth1")
t2 = timeit.Timer("meth2()","from __main__ import meth2")
mean(t1.repeat(1,100000))
дает Out[99]: 7.854323148727417
mean(t2.repeat(1,100000))
дает Out[98]: 7.7788529396057129
Итак, meth2()
немного быстрее. Возможно, потому что это не связано с вызовом flat
.
Ответ 4
Это вычисляет абсолютный максимум, соблюдая произвольный аргумент axis
таким же образом, как и сами np.max
и np.argmax
.
def absmaxND(a, axis=None):
amax = a.max(axis)
amin = a.min(axis)
return np.where(-amin > amax, amin, amax)
Для длинных массивов примерно в 2,5 раза быстрее, чем a.flat[abs(a).argmax()]
даже для простого случая axis=None
- потому что он не отображает abs() исходного большого массива.
Ответ 5
Единственное, о чем я мог думать, что выглядит еще хуже, это:
xmax=x[np.unravel_index(abs(x).argmax(), x.shape)]
Ответ 6
Я думаю, что это довольно простой способ, который может быть немного лучше, если читаемость кода является вашей главной задачей. Но на самом деле ваш путь столь же изящный.
np.min(x) if np.max(abs(x)) == abs(np.min(x)) else np.max(x)