numpy max vs amax vs maximum

132

numpy tem três funções diferentes, que parece que eles podem ser usados para as mesmas coisas --- exceto que numpy.maximumpode unicamente ser utilizado elemento-wise, enquanto numpy.maxe numpy.amaxpode ser usado em eixos específicos, ou todos os elementos. Por que há mais do que apenas numpy.max? Existe alguma sutileza nisso no desempenho?

(Da mesma forma para minvs. aminvs. minimum)

DilithiumMatrix
fonte

Respostas:

164

np.maxé apenas um apelido para np.amax. Essa função funciona apenas em uma única matriz de entrada e localiza o valor do elemento máximo em toda a matriz (retornando um escalar). Como alternativa, é necessário um axisargumento e encontrará o valor máximo ao longo de um eixo da matriz de entrada (retornando uma nova matriz).

>>> 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])

O comportamento padrão de np.maximumé pegar duas matrizes e calcular seu máximo em elementos. Aqui, 'compatível' significa que uma matriz pode ser transmitida para a outra. Por exemplo:

>>> b = np.array([3, 6, 1])
>>> c = np.array([4, 2, 9])
>>> np.maximum(b, c)
array([4, 6, 9])

Mas np.maximumtambém é uma função universal, o que significa que ele possui outros recursos e métodos que são úteis ao trabalhar com matrizes multidimensionais. Por exemplo, você pode calcular o máximo cumulativo em uma matriz (ou em um eixo específico da matriz):

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

Isso não é possível com np.max.

Você pode np.maximumimitar np.maxaté certo ponto ao usar np.maximum.reduce:

>>> np.maximum.reduce(d)
9
>>> np.max(d)
9

O teste básico sugere que as duas abordagens são comparáveis ​​em desempenho; e devem ser, como np.max()realmente exigenp.maximum.reduce o cálculo.

Alex Riley
fonte
1
Obrigado. Obviamente, pode-se usar amaxcom o mesmo objetivo (raiz) que maximum, ou seja, com numpy.amax([a1, a2], axis=0)--- mas isso não é tão otimizado para esse comportamento quanto numpy.maximum? Da mesma forma, as gentilezas adicionadas de numpy.amax(por exemplo, o axisparâmetro) a impedem de ser uma ufunc?
precisa
1
Isso mesmo, amaxnão é otimizado para comparação entre elementos - qualquer entrada precisará ser uma matriz Numpy, para que a lista seja convertida antes da operação ser executada (assumindo que as duas formas sejam iguais). Os documentos para amaxespecificamente dizem que maximumé mais rápido aqui.
Alex Riley #
Na segunda pergunta: acho que amax poderia ser transformado em um ufunc, embora o principal objetivo do ufuncs seja permitir que as operações sejam transmitidas entre matrizes. Parece haver pouca necessidade de fazer maxum unário não funcionar. Eu acho que amaxexistia antes dos ufuncs serem realmente uma coisa (veio do numérico, pai do NumPy), então também é mantido para a posteridade.
Alex Riley #
Aqui maximum.reduce é o preferido para o desempenho: The Python function max() will find the maximum over a one-dimensional array, but it will do so using a slower sequence interface. The reduce method of the maximum ufunc is much faster. Also, the max() method will not give answers you might expect for arrays with greater than one dimension.[...]
Tom Hale
1
@ TomHale: Eu acho que a documentação está se referindo à max()função interna do Python , e não numpy.max(), mas definitivamente vale a pena ressaltar que o Python max()é mais lento.
Alex Riley #
21

Você já declarou por que np.maximumé diferente - ele retorna uma matriz que é o máximo em elementos entre duas matrizes.

Quanto a np.amaxe np.max: ambos chamam a mesma função - np.maxé apenas um alias para np.amaxe calculam o máximo de todos os elementos em uma matriz, ou ao longo de um eixo de uma matriz.

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>
tmdavison
fonte
2
Eu me sinto idiota agora, eu estava fazendo from numpy import max as np_maxapenas para evitar conflitos com os genéricos maxo tempo todo, enquanto eu poderia ter usado apenas amax couros .
Bas Jansen
8

Para completar, em Numpy, existem quatro funções relacionadas máximas . Eles se enquadram em duas categorias diferentes:

  • np.amax/np.max, np.nanmax: para estatísticas de ordem de matriz única
  • e np.maximum, np.fmax: para a comparação de elemento a elemento de duas matrizes

I. Para estatísticas de ordem de matriz única

Propagador de NaNs np.amax/np.maxe seu equivalente ignorante de NaN np.nanmax.

  • np.maxé apenas um apelido de np.amax, então eles são considerados como uma função.

    >>> np.max.__name__
    'amax'
    >>> np.max is np.amax
    True
  • np.maxpropaga NaNs enquanto np.nanmaxignora NaNs.

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

II Para comparação entre elementos de duas matrizes

Propagador de NaNs np.maximume seu equivalente ignorante de NaNs np.fmax.

  • Ambas as funções requerem duas matrizes como os dois primeiros argumentos posicionais para comparação.

    # x1 and x2 must be the same shape or can be broadcast
    np.maximum(x1, x2, /, ...);
    np.fmax(x1, x2, /, ...)
  • np.maximumpropaga NaNs enquanto np.fmaxignora NaNs.

    >>> 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])
  • As funções entre elementos são np.ufunc( Universal Function ) , o que significa que elas têm algumas propriedades especiais que a função Numpy normal não possui.

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

E, finalmente, as mesmas regras se aplicam às quatro funções mínimas relacionadas:

  • np.amin/np.min, np.nanmin;
  • e np.minimum, np.fmin.
YaOzI
fonte
0

np.maximum não apenas compara os elementos, mas também a matriz dos elementos com um único valor

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