2011-12-22 6 views
8

Soy nuevo en python y numpy así que discúlpeme si este problema es tan rudimentario. Tengo una matriz de valores negativos (es clasificada):Long (> 20million element) suma de matriz en python numpy

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

tengo que añadir esta matriz a su duplicado (pero con valores positivos) para encontrar la desviación estándar de la distribución promediada a cero. Así que hago lo siguiente:

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

Hasta ahora todo es muy bueno, pero lo extraño es que la suma de esta nueva matriz no es cero:

>>>numpy.sum(total) 
11610.6 

también la desviación estándar no es en todo lo que esperaba, pero creo que la raíz de ese problema es la misma: ¿por qué la suma no da como resultado cero?

Cuando aplico este método a una pequeña matriz; por ejemplo [-5, -3, -2] la suma se convierte en cero. Así que supongo que el problema radica en la longitud de la matriz (más de 20 millones de elementos). ¿Hay alguna forma de lidiar con este problema?

Si alguien pudiera ayudarme con esto, estaría muy agradecido.

+2

¿'math.fsum (total)' devuelve '0'? – jfs

+0

Sí lo hace !!! ¡¡¡GUAU!!! ¿Quieres decir que no debería haber usado numpy en absoluto, estaba en la idea errónea de que Numpy es la mejor herramienta para trabajar en matrices !!! Pero al buscar en http://docs.python.org/py3k/library/math.html#module-math, no veo ninguna herramienta para calcular la Desviación estándar. ¿Qué propones? – makhlaghi

+0

No. 'fsum()' es solo para una verificación de cordura que su código no tiene otro error que no sea perder precisión durante la suma. ['numpy.std()'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.std.html) podría usarse para la Desviación estándar. Pruebe 'np.std (total, dtype = np.float64)'. – jfs

Respuesta

3

Como se señala en los comentarios, se obtienen problemas de redondeo de flotantes al sumar muchos millones de números con signo igual. Una posible forma de evitar esto podría ser para mezclar los números positivos y negativos de la matriz combinada, por lo que los resultados intermedios al resumir siempre se quedan más o menos dentro del mismo orden de magnitud:

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

Ahora combined.sum() debe estar muy cerca cero.

Quizás este enfoque también ayude a mejorar la precisión en el cálculo de la desviación estándar.

+0

La suma llegó a ser exactamente cero ahora, también lo hizo la media que tampoco era cero. pero lo más extraño es que la desviación estándar no cambió de lo que era antes. A menos que 'numpy.std()' use otro método para calcular la suma (por ejemplo, en el módulo 'math.fsum()') este resultado no es aceptable porque while 'numpy.sum()' y 'numpy.mean() 'changed,' numpy.std() 'no !!!! – makhlaghi

+1

Tendrá que implementar 'std()' usted mismo usando las técnicas que describimos para hacer las sumas en la fórmula. –

+0

Escribí un programa para calcular 'std()' self; encontrar la diferencia de cada valor con el promedio en paquetes de 10,000 elementos, sumar los resultados y finalmente dividir por el número de elementos y encontrar la raíz cuadrada. Tardó unos 15 minutos en calcular la desviación estándar para todos los elementos> 25 millones y encontró exactamente el mismo valor que 'numpy.std()' (¡que tomó una fracción de segundo!). Este conjunto de datos fue una prueba para mi algoritmo: como dije, conocía la desviación estándar desde el principio. Comprobaré el origen de esa desviación estándar para ver si es correcta o no. – makhlaghi

Cuestiones relacionadas