如何在numpy矩阵中获得绝对值中的最高元素?

时间:2013-07-22 18:00:49

标签: python numpy

这是我目前正在做的事情,它有效,但有点麻烦:

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

8 个答案:

答案 0 :(得分:27)

您要查找的值必须为x.max()x.min(),以便您可以

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

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

答案 1 :(得分: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

答案 2 :(得分:3)

这个快速计算绝对最大值 - 尊重任意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()。

答案 3 :(得分:2)

编辑 :我的回答是偏离主题的,抱歉。正如Ophion指出这将返回索引而不是值 - 您必须使用flat和我的“xmax”(实际上是“xmaxInd”)才能获得正确的值。我觉得你的解决方案是最好的。


经过实验,我意识到你可以这样做:

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 :(得分:1)

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

xmax=x[np.unravel_index(abs(x).argmax(), x.shape)]

答案 5 :(得分:0)

我认为这是一种非常直接的方式,如果代码可读性是您主要关心的话,可能会稍好一些。但实际上,你的方式同样优雅。

np.min(x) if np.max(abs(x)) == abs(np.min(x)) else np.max(x)

答案 6 :(得分:0)

我用它

services.AddJsReport(new LocalReporting()
                    .UseBinary(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
                                        jsreport.Binary.JsReportBinary.GetBinary() :
                                        jsreport.Binary.Linux.JsReportBinary.GetBinary())
                    .KillRunningJsReportProcesses()
                    .AsUtility()
                    .Create());

它快了将近4倍(60毫秒对230毫秒)!

答案 7 :(得分:0)

最紧凑的方式可能是:

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

默认情况下,.max()方法直接在扁平化数组上操作(取自NumPy documentation)。因此,该操作会寻找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"