nueva solución
Después de mirar la respuesta de Joe Kington, decidí estudiar el código corrcoef()
y se inspiró para realizar la siguiente implementación.
ms = data.mean(axis=1)[(slice(None,None,None),None)]
datam = data - ms
datass = np.sqrt(scipy.stats.ss(datam,axis=1))
for i in xrange(rows):
temp = np.dot(datam[i:],datam[i].T)
rs = temp/(datass[i:]*datass[i])
Cada ciclo genera los coeficientes de Pearson entre la fila iy las filas i hasta la última fila. Es muy rápido. Es al menos 1.5 veces más rápido que usar corrcoef()
solo porque no calcula de forma redundante los coeficientes y algunas otras cosas. También será más rápido y no le dará los problemas de memoria con una matriz de 50,000 filas porque entonces puede elegir almacenar cada conjunto de r o procesarlas antes de generar otro conjunto. Sin almacenar ninguno de los r a largo plazo, pude obtener el código anterior para ejecutar en 50,000 x 10 conjunto de datos generados aleatoriamente en menos de un minuto en mi portátil bastante nuevo.
antigua solución
En primer lugar, yo no recomendaría imprimir el r de la pantalla. Para 100 filas (10 columnas), esta es una diferencia de 19.79 segundos con la impresión frente a 0.301 segundos sin usar el código. Simplemente almacene las "r" y úselas más adelante si lo desea, o haga algún procesamiento con ellas a medida que avance, como buscar algunas de las r más grandes.
En segundo lugar, puede obtener algunos ahorros al no calcular algunas cantidades de forma redundante. El coeficiente de Pearson se calcula en scipy usando algunas cantidades que puede precalcular en lugar de calcular cada vez que se utiliza una fila. Además, no se está utilizando el valor de p (que también es devuelto por pearsonr()
así que vamos a rascar eso también con el siguiente código:.
r = np.zeros((rows,rows))
ms = data.mean(axis=1)
datam = np.zeros_like(data)
for i in xrange(rows):
datam[i] = data[i] - ms[i]
datass = scipy.stats.ss(datam,axis=1)
for i in xrange(rows):
for j in xrange(i,rows):
r_num = np.add.reduce(datam[i]*datam[j])
r_den = np.sqrt(datass[i]*datass[j])
r[i,j] = min((r_num/r_den), 1.0)
consigo una aceleración de alrededor de 4,8 veces por encima del scipy recta código cuando eliminé el valor de p-cosas - 8.8x si dejo las cosas de valor p allí (utilicé 10 columnas con cientos de filas). También verifiqué que da los mismos resultados. Esto no es una gran mejora, pero podría ayudar.
En última instancia, está atascado con el problema de que está calculando (50000) * (50001)/2 = 1,250,025,000 coeficientes de Pearson (si estoy contando correctamente). Eso es mucho. Por cierto, realmente no hay necesidad de calcular el coeficiente de Pearson de cada fila consigo mismo (será igual a 1), pero eso solo le ahorra el cálculo de 50,000 coeficientes de Pearson. Con el código anterior, espero que tome aproximadamente 4 1/4 horas para realizar su cálculo si tiene 10 columnas para sus datos en función de mis resultados en conjuntos de datos más pequeños.
Puede obtener alguna mejora si toma el código anterior en Cython o algo similar. Espero que tengas una mejora de hasta 10 veces con respecto a Scipy si tienes suerte. Además, según lo sugerido por pyInTheSky, puede hacer un multiprocesamiento.
Me gustaría ver un ejemplo más completo de lo que quiere decir aquí. – vgoklani
Creo que mi respuesta está muy alejada de esta pregunta en este momento, pero si está interesado en la multiprocesión, consulte: http://docs.python.org/library/multiprocessing.html ... esencialmente en lugar de recorrer filas , crea una función y un grupo de subprocesos y simplemente hace p.map (myfunc, xrange (rows)) – pyInTheSky