Domanda Perché numpy ha una funzione corrispondente per molti metodi ndarray?


Alcuni esempi:

numpy.sum()
ndarray.sum()
numpy.amax()
ndarray.max()
numpy.dot()
ndarray.dot()

... e molto altro ancora. È per supportare qualche codice legacy, o c'è una ragione migliore per questo? E, scelgo solo in base a come il mio codice 'sembra', o è uno dei due modi migliori rispetto all'altro?

Posso immaginare che uno potrebbe volere numpy.dot() usare reduce (per esempio., reduce(numpy.dot, A, B, C, D)) ma non penso che sarebbe utile per qualcosa di simile numpy.sum().


10
2018-03-18 11:22


origine


risposte:


Come altri hanno notato, le funzioni NumPy e i metodi dell'array identicamente nominati sono spesso equivalenti (finiscono per chiamare lo stesso codice sottostante). Uno potrebbe essere preferito all'altro se è più facile da leggere.

Tuttavia, in alcuni casi i due si comportano in modo leggermente diverso. In particolare, usando il ndarray il metodo a volte sottolinea il fatto che il metodo sta modificando l'array sul posto.

Per esempio, np.resize restituisce a nuovo array con la forma specificata. D'altra parte, ndarray.resize cambia la forma della matrice sul posto. Anche i valori di riempimento utilizzati in ciascun caso sono diversi.

Allo stesso modo, a.sort() ordina l'array a sul posto, mentre np.sort(a) restituisce una copia ordinata.


9
2018-03-18 13:31



Nella maggior parte dei casi il metodo è la versione compilata di base. La funzione usa quel metodo quando disponibile, ma ha anche una specie di backup quando l'argomento non è una matrice. Aiuta a guardare il codice e / o i documenti della funzione o del metodo.

Ad esempio se in Ipython Chiedo di guardare il codice per il metodo della somma, vedo che è un codice compilato

In [711]: x.sum??
Type:        builtin_function_or_method
String form: <built-in method sum of numpy.ndarray object at 0xac1bce0>
...
Refer to `numpy.sum` for full documentation.

Fai lo stesso su np.sum Ricevo molte linee di documentazione oltre a qualche codice Python:

   if isinstance(a, _gentype):
        res = _sum_(a)
        if out is not None:
            out[...] = res
            return out
        return res
    elif type(a) is not mu.ndarray:
        try:
            sum = a.sum
        except AttributeError:
            return _methods._sum(a, axis=axis, dtype=dtype,
                                out=out, keepdims=keepdims)
        # NOTE: Dropping the keepdims parameters here...
        return sum(axis=axis, dtype=dtype, out=out)
    else:
        return _methods._sum(a, axis=axis, dtype=dtype,
                            out=out, keepdims=keepdims)

Se chiamo np.sum(x) dove x è un array, finisce per chiamare x.sum():

    sum = a.sum
    return sum(axis=axis, dtype=dtype, out=out)

np.amax simile (ma più semplice). Si noti che il np. la forma può gestire un oggetto che non è una matrice (che non ha il metodo), ad es. una lista: np.amax([1,2,3]).

np.dot e x.dot entrambi mostrano come funzione 'built-in', quindi non possiamo dire nulla sulla priorità. Probabilmente entrambi finiscono per chiamare qualche funzione C sottostante.

np.reshape è un altro che delega, se possibile:

try:
    reshape = a.reshape
except AttributeError:
    return _wrapit(a, 'reshape', newshape, order=order)
return reshape(newshape, order=order)

Così np.reshape(x,(2,3)) è identico in funzionalità a x.reshape((2,3)). Ma il _wrapit espressione consente np.reshape([1,2,3,4],(2,2)).

np.sort restituisce una copia eseguendo un ordinamento in posto su una copia:

a = asanyarray(a).copy()
a.sort(axis, kind, order)
return a

x.resize è integrato, mentre np.resize finisce per fare un np.concatenate e reshape.

Se la matrice è una sottoclasse, come matrice o mascherata, potrebbe avere una propria variante. L'azione di una matrice .sum è:

return N.ndarray.sum(self, axis, dtype, out, keepdims=True)._collapse(axis)

5
2018-03-18 15:36



Elaborando il commento di Peter per la visibilità:

Potremmo renderlo più coerente rimuovendo i metodi da ndarray e attenendoci alle sole funzioni. Ma questo è impossibile perché spezzerebbe il codice esistente di tutti che usa metodi.

Oppure, potremmo spostare tutte le funzioni anche come metodi. Ma questo è impossibile perché nuovi utenti e pacchetti definiscono costantemente nuove funzioni. Inoltre continuando a moltiplicare questi metodi duplicati viola "dovrebbe esserci un modo ovvio per farlo".

Se potessimo tornare indietro nel tempo, probabilmente direi di non avere affatto questi metodi su ndarray e di usare esclusivamente le funzioni. ... Quindi questo tutto sostiene l'utilizzo esclusivo delle funzioni

Problema di numpy: maggiore coerenza con i metodi array # 7452


0
2017-07-02 21:19