2011-12-22 6 views
8

Sono nuovo in Python e Numpy quindi scusami se questo problema è così rudimentale! Ho un array di valori negativi (è ordinato):Sommario array lungo (> 20 milioni di elementi) in python numpy

>>>neg 
[ -1.53507843e+02 -1.53200012e+02 -1.43161987e+02 ..., -6.37326136e-1 -3.97518490e-10 -3.73480691e-10] 
>>>neg.shape 
(12922508,) 

ho bisogno di aggiungere questo array alla sua duplice copia (ma con valori positivi) per trovare la deviazione standard della distribuzione in media a zero. Così faccio la seguente:

>>>pos=-1*neg 
>>>pos=pos[::-1] #Just to make it look symmetric for the display bellow! 
>>>total=np.hstack((neg,pos)) 
>>>total 
[-153.50784302 -153.20001221 -143.1619873 ..., 143.1619873 153.20001221 153.50784302] 
>>>total.shape 
(25845016,) 

Finora tutto è molto buona, ma la cosa strana è che la somma di questa nuova serie non è zero:

>>>numpy.sum(total) 
11610.6 

La deviazione standard non è anche al tutto vicino a quello che mi aspettavo, ma immagino che la radice di questo problema sia la stessa: perché la somma non è zero?

Quando si applica questo metodo a un piccolo array; ad esempio [-5, -3, -2] la somma diventa zero. Quindi immagino che il problema risieda nella lunghezza della matrice (oltre 20 milioni di elementi). C'è un modo per affrontare questo problema?

Se qualcuno mi può aiutare su questo sarei molto grato.

+2

Does 'math.fsum (total)' return '0'? – jfs

+0

Sì, lo fa !!! WOW!!! Vuoi dire che non avrei dovuto usare affatto Numpy, ero nel malinteso che numpy fosse lo strumento migliore per lavorare sugli array !!! Ma guardando in http://docs.python.org/py3k/library/math.html#module-math non vedo nessuno strumento per il calcolo della deviazione standard. Cosa vorresti proporre? – makhlaghi

+0

No. 'fsum()' serve solo per verificare se il tuo codice non ha altri bug oltre a perdere precisione durante la sommatoria. ['numpy.std()'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.std.html) potrebbe essere usato per la deviazione standard. Prova 'np.std (totale, dtype = np.float64)'. – jfs

risposta

3

Come indicato nei commenti, si ottengono problemi di arrotondamento float dalla somma di molti milioni di numeri con segno uguale. Un modo possibile intorno a questa potrebbe essere quella di mescolare numeri positivi e negativi nella matrice combinato, in modo che eventuali risultati intermedi mentre sommando sempre rimanere o meno all'interno dello stesso ordine di grandezza:

neg = -100*numpy.random.rand(20e6) 
pos = -neg 
combined = numpy.zeros(len(neg)+len(pos)) 
combined[::2] = neg 
combined[1::2] = pos 

Ora combined.sum() dovrebbe essere abbastanza vicino al zero.

Forse questo approccio aiuterà anche a migliorare la precisione nel calcolo della deviazione standard.

+0

La somma è diventata esattamente zero ora, così come la media che era anche zero. ma la cosa molto strana è che la deviazione standard non è cambiata rispetto a prima. A meno che 'numpy.std()' usi un altro metodo per calcolare la somma (per esempio nel modulo 'math.fsum()') questo risultato non è accettabile perché mentre 'numpy.sum()' e 'numpy.mean() 'cambiato,' numpy.std() 'non ha !!!! – makhlaghi

+1

Sarà necessario implementare 'std()' usando le tecniche che abbiamo descritto per eseguire le sommatorie nella formula. –

+0

Ho scritto un programma per calcolare 'std()' my self; trovare la differenza di ogni valore con la media in pacchetti di 10.000 elementi, sommando i risultati e infine dividendo per il numero di elementi e trovando la radice quadrata. Ci sono voluti circa 15 minuti per calcolare la deviazione standard per tutti gli elementi> 25 milioni e ha trovato esattamente lo stesso valore di 'numpy.std()' (che ha richiesto una frazione di secondo!). Questo set di dati era un test per il mio algoritmo: come ho detto, conoscevo la deviazione standard dall'inizio. Controllerò la fonte di tale deviazione standard per vedere se è corretta o meno! – makhlaghi

Problemi correlati