2009-04-21 15 views

risposta

95

Uno non dovrebbe pensarci troppo. In definitiva è meglio per la salute mentale e la longevità dell'individuo.

La curiosa situazione con i tipi scalari di Numpy è stata al di fuori dal fatto che non esiste un modo aggraziato e coerente per degradare la matrice 1x1 in tipi scalari. Anche se matematicamente sono la stessa cosa, sono gestiti da un codice molto diverso.

Se si sta facendo una quantità di codice scientifico, alla fine si vorrebbe cose come max(a) per lavorare su matrici di tutte le dimensioni, anche scalari. Matematicamente, questa è una cosa perfettamente ragionevole da aspettarsi. Tuttavia per i programmatori ciò significa che qualsiasi cosa presenti in Numpy deve avere gli attributi .shape e .ndim, così almeno gli ufunc non devono fare controlli espliciti sui propri input per i 21 possibili tipi scalari in Numpy.

D'altra parte, dovrebbero anche funzionare con le librerie Python esistenti che fa fare controlli di tipo espliciti su tipo scalare. Questo è un dilemma, dal momento che un ndarray di Numpy deve cambiare individualmente il suo tipo quando è stato ridotto a uno scalare, e non c'è modo di sapere se ciò si è verificato senza che abbia effettuato controlli su tutti gli accessi. In realtà, quella via probabilmente renderebbe il lavoro ridicolmente lento con standard di tipo scalare.

soluzione dello sviluppatore Numpy è quello di ereditare da entrambe le scalari ndarray e Python per il proprio tipo scalary, in modo che tutti gli scalari hanno anche .shape, .ndim, .T, ecc ecc La matrice 1x1 sarà ancora lì, ma il suo utilizzo sarà scoraggiato se sai che avrai a che fare con uno scalare. Anche se questo dovrebbe funzionare bene in teoria, di tanto in tanto si poteva ancora vedere alcuni luoghi dove hanno perso con il rullo di vernice, e le brutte interiora sono esposti gli occhi di tutti:

>>> from numpy import * 
>>> a = array(1) 
>>> b = int_(1) 
>>> a.ndim 
0 
>>> b.ndim 
0 
>>> a[...] 
array(1) 
>>> a[()] 
1 
>>> b[...] 
array(1) 
>>> b[()] 
1 

Non c'è davvero alcun motivo per cui a[...] e a[()] dovrebbe restituire cose diverse, ma lo fa. Ci sono proposte in atto per cambiare questo, ma sembra che abbiano dimenticato di finire il lavoro per gli array 1x1.

Un problema potenzialmente più grande, e probabilmente non risolvibile, è il fatto che gli scalari Numpy sono immutabili. Quindi "irrorare" uno scalare in un narray, matematicamente l'operazione aggiunta di collassare un array in uno scalare, è un PITA da implementare. Non si può effettivamente far crescere uno scalare Numpy, non può, per definizione, essere gettato in un ndarray, anche se newaxis funziona misteriosamente su di esso:

>>> b[0,1,2,3] = 1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'numpy.int32' object does not support item assignment 
>>> b[newaxis] 
array([1]) 

in Matlab, cresce la dimensione di uno scalare è un perfettamente accettabile e senza cervello operazione. In Numpy devi attaccare lo stereotipo a = array(a) ovunque tu sia pensi che avresti la possibilità di iniziare con uno scalare e finire con un array.Capisco perché Numpy deve essere così bello da interpretare con Python, ma ciò non cambia il fatto che molti nuovi switcher sono profondamente confusi su questo. Alcuni hanno una memoria esplicita di lottare con questo comportamento e alla fine perseveranti, mentre altri che sono troppo lontani sono generalmente lasciati con una profonda cicatrice mentale informe che frequentemente perseguita i loro sogni più innocenti. È una brutta situazione per tutti.

+21

+1 per l'introduzione filosofica :-) –

+3

Hai considerato una carriera secondaria? – KobeJohn

+4

Gran parte di questo sembra essere il modo più semplice di guardare le cose -_ "Non si può realmente crescere uno scalare Numpy" _ - né si può coltivare un np.array. Essere espliciti riguardo alle dimensioni rende più difficile il comportamento accidentale di O (N^2). _ "non può essere castato per definizione in un narray" _ - questo è ciò che fa "np.asarray (scalare)". _ "la matrice 1x1 ..." _ - pensare alle cose come intrinsecamente 2D, o come matrici, è inutile qui – Eric

4

È necessario creare l'array scalare un po 'diverso:

>>> x = numpy.float64(1.111) 
>>> x 
1.111 
>>> numpy.isscalar(x) 
True 
>>> numpy.ndim(x) 
0 

Sembra scalars in numpy può essere un concetto diverso po' da quello che può essere utilizzato per dal punto di vista puramente matematico. Immagino che tu stia pensando in termini di matrici scalari?

Problemi correlati