2016-04-09 11 views
6

Ho una matrice di data e ora, aumentando per ogni riga nella 2a colonna della matrice X. Calcolo il valore medio dei timestamp ed è maggiore del valore massimo. Sto usando una memmap numpy per l'archiviazione. Perché sta succedendo?media numpy è maggiore di max per memmap

>>> self.X[:,1] 
memmap([ 1.45160858e+09, 1.45160858e+09, 1.45160858e+09, ..., 
    1.45997146e+09, 1.45997683e+09, 1.45997939e+09], dtype=float32) 
>>> np.mean(self.X[:,1]) 
1.4642646e+09 
>>> np.max(self.X[:,1]) 
memmap(1459979392.0, dtype=float32) 
>>> np.average(self.X[:,1]) 
1.4642646e+09 
>>> self.X[:,1].shape 
(873608,) 
>>> np.sum(self.X[:,1]) 
memmap(1279193195216896.0, dtype=float32) 
>>> np.sum(self.X[:,1])/self.X[:,1].shape[0] 
memmap(1464264515.9120522) 

EDIT: Ho caricato il file memmap qui. http://www.filedropper.com/x_2 Ecco come lo carico.

filepath = ... 
shape = (875422, 23) 
X = np.memmap(filepath, dtype="float32", mode="r", shape=shape) 

# I preprocess X by removing rows with all 0s 
# note this step doesn't affect the problem 
to_remove = np.where(np.all(X == 0, axis=1))[0] 
X = np.delete(X, to_remove, axis=0) 
+0

cambia il comportamento se si prova con 'np.array (self.x)' invece di 'self.X', o' np.array (self.x [:, 1]) 'invece di 'self.X [:, 1]'? – user2357112

+0

@ user2357112 no, restituisce comunque la media errata – siamii

+0

@siamii: si tratta di un problema di accumulo. Si dovrebbero usare accumulatori float64 per array di grandi dimensioni. Controlla la risposta per maggiori dettagli. – Vasanth

risposta

6

Questo non è un problema di numpy o memmap. Il problema è con virgola mobile, float32 per la precisione. Puoi vedere lo stesso errore in altri linguaggi come C++.

L'accumulatore float32 utilizzato diventa impreciso man mano che vengono aggiunti sempre più numeri.

In [26]: a = np.ones((1024,1024), dtype=np.float32)*4567 

In [27]: a.min() 
Out[27]: 4567.0 

In [28]: a.max() 
Out[28]: 4567.0 

In [29]: a.mean() 
Out[29]: 4596.5264 

Questo non accadrà a np.float64 tipo (dà ancora un po 'di respiro).

In [30]: a = np.ones((1024,1024), dtype=np.float64)*4567 

In [31]: a.min() 
Out[31]: 4567.0 

In [32]: a.mean() 
Out[32]: 4567.0 

È possibile effettuare mean() di utilizzare un buffer float64 specificando esplicitamente.

In [12]: a = np.ones((1024,1024), dtype=np.float32)*4567 

In [13]: a.mean(dtype=np.float64) 
Out[13]: 4567.0 
+0

Specificare dtype in media significa solo allocare 1 (o O (1)) float64 in memoria o lancia l'intero array? Assumerei il primo, ma solo curioso. – Paul

+0

È solo il tipo di dati dell'accumulatore utilizzato per il calcolo. Non alloca una nuova matrice 'float64'. – Vasanth

+0

@Vasanth puoi dare una risposta dettagliata al motivo per cui ciò accade? –

Problemi correlati