numpy的max、amax和maximum有什么区别?

217

NumPy有三个看起来可以用于相同事情的不同函数 --- 除了numpy.maximum只能针对每个元素使用,而numpy.maxnumpy.amax可以用于特定轴或所有元素。为什么不止有numpy.max?这是否涉及到性能上的微妙差别?

(类似地,对于min vs. amin vs. minimum)

4个回答

254

np.maxnp.amax 的别名。该函数仅适用于 单个 输入数组,并查找该整个数组中最大元素的值(返回一个标量)。或者,它可以使用 axis 参数,并在输入数组的轴上找到最大值(返回一个新数组)。

>>> a = np.array([[0, 1, 6],
                  [2, 4, 1]])
>>> np.max(a)
6
>>> np.max(a, axis=0) # max of each column
array([2, 4, 6])
np.maximum 的默认行为是取 两个 数组并计算它们的逐元素最大值。这里,“兼容”指的是一个数组可以被广播到另一个数组。例如:
>>> b = np.array([3, 6, 1])
>>> c = np.array([4, 2, 9])
>>> np.maximum(b, c)
array([4, 6, 9])

但是np.maximum也是一个通用函数,这意味着它还有其他功能和方法,在处理多维数组时非常有用。例如,您可以计算数组(或数组的特定轴)上的累积最大值:

>>> d = np.array([2, 0, 3, -4, -2, 7, 9])
>>> np.maximum.accumulate(d)
array([2, 2, 3, 3, 3, 7, 9])

这不是使用np.max能实现的。
在使用np.maximum.reduce时,你可以让np.maximum在一定程度上模仿np.max
>>> np.maximum.reduce(d)
9
>>> np.max(d)
9

基本测试表明这两种方法在性能方面是可比较的;它们应该是可比较的,因为 np.max() 实际上调用了 np.maximum.reduce 来进行计算。

1
谢谢。显然,人们可以像使用maximum一样使用amax来实现相同的(根)目的,即使用numpy.amax([a1, a2], axis=0) --- 但是这是否与numpy.maximum一样优化了这种行为?同样,numpy.amax的附加好处(例如axis参数)是否排除了它成为ufunc的可能性? - DilithiumMatrix
2
没错,在这种情况下,amax 没有针对逐元素比较进行优化 - 任何输入都需要是一个 Numpy 数组,因此在操作运行之前,该列表将被转换(假设两个形状相同)。amax 的文档明确表示 maximum 在这里更快。 - Alex Riley
关于第二个问题:我猜amax可以被制作成一个ufunc,尽管ufunc的主要目的是允许在数组之间广播操作。似乎没有必要将max制作成一元ufunc。我认为amax在ufunc真正成为一件事情之前就已经存在了(它来自numeric,NumPy的父类),因此也为了纪念而保留。 - Alex Riley
1
在这里,maximum.reduce 是性能更好的选择:Python 函数 max() 可以找到一维数组中的最大值,但是它会使用较慢的序列接口来实现。最大 ufunc 的 reduce 方法要快得多。此外,max() 方法对于具有大于一维的数组不会给出您可能期望的答案。 [...] - Tom Hale
1
@TomHale:我认为文档指的是Python内置的max()函数,而不是numpy.max(),但值得指出的是Python的max()速度较慢。 - Alex Riley
有没有办法检测哪些函数是别名?Python 这么不透明,人们被迫做各种基准测试以区分各种完全相同的函数,这似乎相当荒谬。 - berniethejet

26

你已经说明了np.maximum的不同之处 - 它返回两个数组之间逐元素的最大值数组。

至于np.amaxnp.max:它们都调用同一个函数 - np.max只是np.amax的别名,并计算数组或沿着数组轴的所有元素的最大值。

In [1]: import numpy as np

In [2]: np.amax
Out[2]: <function numpy.core.fromnumeric.amax>

In [3]: np.max
Out[3]: <function numpy.core.fromnumeric.amax>

3
现在我感觉很蠢,我一直在使用from numpy import max as np_max来避免与通用的max冲突,而我本可以只是用amax 躲起来 - Bas Jansen

15
为了完整,NumPy中有四个与最大值有关的函数。它们分为两类:

  • np.amax/np.maxnp.nanmax:用于单个数组的顺序统计量
  • np.maximumnp.fmax:用于对两个数组进行逐元素比较

I. 用于单个数组的顺序统计量

NaNs传播器np.amax/np.max及其忽略NaN的对应函数np.nanmax

  • np.max只是np.amax的别名,因此它们被视为一个函数。

>>> np.max.__name__
'amax'
>>> np.max is np.amax
True
  • np.max 会传播NaN值,而 np.nanmax 则会忽略NaN值。

  • >>> np.max([np.nan, 3.14, -1])
    nan
    >>> np.nanmax([np.nan, 3.14, -1])
    3.14
    

    II. 用于逐元素比较两个数组的函数

    np.maximum与其忽略NaN值的对应函数np.fmax可以处理NaN值。

    • 这两个函数都需要将要与之比较的两个数组作为第一个和第二个位置参数。

    # x1 and x2 must be the same shape or can be broadcast
    np.maximum(x1, x2, /, ...);
    np.fmax(x1, x2, /, ...)
    
  • np.maximum会传播NaN值,而np.fmax会忽略NaN值。

  • >>> np.maximum([np.nan, 3.14, 0], [np.NINF, np.nan, 2.72])
    array([ nan,  nan, 2.72])
    >>> np.fmax([np.nan, 3.14, 0], [np.NINF, np.nan, 2.72])
    array([-inf, 3.14, 2.72])
    
  • 逐元素函数是np.ufunc(通用函数),这意味着它们具有一些常规Numpy函数没有的特殊属性。

  • >>> type(np.maximum)
    <class 'numpy.ufunc'>
    >>> type(np.fmax)
    <class 'numpy.ufunc'>
    >>> #---------------#
    >>> type(np.max)
    <class 'function'>
    >>> type(np.nanmax)
    <class 'function'>
    

    最后,相同的规则适用于四个minimum相关函数:

    • np.amin/np.minnp.nanmin
    • 以及np.minimumnp.fmin

    3

    np.maximum 不仅可以逐个元素地比较,还可以将数组逐个元素地与单个值进行比较

    >>>np.maximum([23, 14, 16, 20, 25], 18)
    array([23, 18, 18, 20, 25])
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接