27

这是我目前正在做的事情,它可以工作,但有点麻烦:

x = np.matrix([[1, 1], [2, -3]])
xmax = x.flat[abs(x).argmax()]
4

9 回答 9

40

您正在寻找的价值必须是您x.max()可以x.min()做到的

max(x.min(), x.max(), key=abs)

这类似于 aestrivex 的解决方案,但可能更具可读性?x.min()请注意,这将在和x.max()具有相同绝对值的情况下返回最小值,例如-55。如果您有偏好,只需max相应地订购输入。

于 2015-01-12T14:14:50.523 回答
6

我正在寻找一种方法来获取沿指定轴的 N 维数组的最大绝对值的有符号值,这些答案都没有处理。所以,我整理了一个函数来完成它。没有承诺,但据我测试它是有效的:

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
于 2014-05-05T05:27:12.767 回答
6

这个可以快速计算绝对最大值——尊重任意axis参数的方式np.maxnp.argmax它们自己的方式相同。

def absmaxND(a, axis=None):
    amax = a.max(axis)
    amin = a.min(axis)
    return np.where(-amin > amax, amin, amax)

a.flat[abs(a).argmax()]对于长数组,它甚至比简单情况快 2.5 倍axis=None——因为它不会渲染原始大数组的 abs()。

于 2016-08-25T18:21:04.373 回答
5

最紧凑的方式可能是:

x_max = np.abs(x).max()  

默认情况下,该.max()方法直接对展平数组进行操作(取自NumPy 文档)。因此该操作查找 n 维数组的最大绝对值np.abs(x)


执行时间处理时间

此外,它比问题的解决方案快 2000 倍以上。考虑到在 Дмитрий Пасько 的示例中应用的 IPython%time魔术函数,我得到(在带有 Python 3.8 和 NumPy 1.19.1 的 MacBook Pro 2015 上):

x = np.random.rand(50000, 500) - 0.5

# numpy solution
x_max = np.abs(x).max()
"Wall time: 67.7 µs"

# question's solution
%time xmax = x[abs(x).argmax()]
"Wall time: 157 ms"

# Daniel's solution
%time xmax=x[np.unravel_index(abs(x).argmax(), x.shape)] 
"Wall time: 88.9 µs"

# Дмитрий Пасько's solution
%time newdt = np.array([dt.min(),dt.max()])
  ... xmax = newdt.flat[abs(newdt).argmax()]
"Wall time: 26.7 ms"
于 2020-10-12T01:46:08.730 回答
3

编辑:我的回答是题外话,对不起。正如 Ophion 指出的那样,这将返回索引,而不是值 - 你必须使用flat我的“xmax”(实际上是“xmaxInd”)来获得正确的值。Ergo 我认为您的解决方案是最好的。


经过一番试验后,我意识到你可以这样做:

x = np.matrix([[1,1], [2,-3]])
absX = abs(x)
xmax = argmax(absX)

似乎 numpy 允许您使用矩阵absargmax和 。多么方便!

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

于 2013-07-22T18:25:45.017 回答
1

我唯一能想到的,看起来更糟的是:

xmax=x[np.unravel_index(abs(x).argmax(), x.shape)]
于 2013-07-22T18:01:47.850 回答
0

我用这个

dt = np.random.rand(50000,500)-0.5
# ur
xmax = dt.flat[abs(dt).argmax()] #230 ms

# new
newdt = np.array([dt.min(),dt.max()]) # 56ms
xmax = newdt.flat[abs(newdt).argmax()] # 4ms

它几乎快了 4 倍(60 毫秒对 230 毫秒)!!

于 2020-05-22T19:34:06.110 回答
0

请原谅死灵,但我似乎无法评论JoeCondron的回答。

我喜欢:

max(x.min(), x.max(), key=abs) 

但我相信它可以进一步简化:

max(x, key=abs)

似乎对我有用(或非一维):

max(x.flat, key=abs)
于 2021-10-07T22:44:01.240 回答
-1

我认为这是一种非常简单的方法,如果代码可读性是您的主要关注点,它可能会稍微好一些。但实际上,你的方式同样优雅。

np.min(x) if np.max(abs(x)) == abs(np.min(x)) else np.max(x)
于 2013-07-22T18:57:57.720 回答