Cómo leer en una lista de bordes para hacer una matriz dispersa escéptica

Tengo un archivo grande donde cada línea tiene un par de cadenas de 8 caracteres. Algo como:

ab1234gh iu9240gh 

en cada linea

Este archivo realmente representa un gráfico y cada cadena es un ID de nodo. Me gustaría leer en el archivo y hacer directamente una matriz de adyacencia escasa dispersa. Luego ejecutaré PCA en esta matriz usando una de las muchas herramientas disponibles en Python

¿Hay una forma clara de hacer esto o debo hacer primero un gráfico en la RAM y luego convertirlo en una matriz dispersa? Como el archivo es grande, me gustaría evitar pasos intermedios si es posible.

En última instancia, introduciré la dispersa matriz de adyacencia en http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.TruncatedSVD.html#sklearn.decomposition.TruncatedSVD .

Creo que esta es una tarea regular en sklearn , por lo que debe haber alguna herramienta en el paquete que haga esto, o una respuesta en otras preguntas de SO. Necesitamos agregar la etiqueta correcta.

Pero solo trabajando desde mi conocimiento de numpy y sparse , donde haría lo que haría:

Haga una muestra 2d array – N filas, 2 columnas con valores de caracteres:

 In [638]: A=np.array([('a','b'),('b','d'),('a','d'),('b','c'),('d','e')]) In [639]: A Out[639]: array([['a', 'b'], ['b', 'd'], ['a', 'd'], ['b', 'c'], ['d', 'e']], dtype=' 

Use np.unique para identificar las cadenas únicas y, como bonificación, un mapa de esas cadenas a la matriz original. Este es el caballo de batalla de la tarea.

 In [640]: k1,k2,k3=np.unique(A,return_inverse=True,return_index=True) In [641]: k1 Out[641]: array(['a', 'b', 'c', 'd', 'e'], dtype=' 

Puedo cambiar la forma de la matriz inverse para identificar la fila y la columna para cada entrada en A

 In [644]: rows,cols=k3.reshape(A.shape).T In [645]: rows Out[645]: array([0, 1, 0, 1, 3], dtype=int32) In [646]: cols Out[646]: array([1, 3, 3, 2, 4], dtype=int32) 

con aquellos es trivial construir una matriz dispersa que tenga 1 en cada 'intersección'.

 In [648]: M=sparse.coo_matrix((np.ones(rows.shape,int),(rows,cols))) In [649]: M Out[649]: <4x5 sparse matrix of type '' with 5 stored elements in COOrdinate format> In [650]: MA Out[650]: array([[0, 1, 0, 1, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 1]]) 

la primera fila, a tiene valores en la 2da y 4ta col, b y d . y así.

============================

Originalmente tuve:

 In [648]: M=sparse.coo_matrix((np.ones(k1.shape,int),(rows,cols))) 

Esto está mal. La matriz de data debe coincidir con las rows y cols en forma. Aquí no generó un error porque k1 tiene el mismo tamaño. Pero con una mezcla diferente los valores únicos podrían generar un error.

====================

Este enfoque supone que toda la base de datos, A puede cargarse en la memoria. unique probablemente requiere un uso de memoria similar. Inicialmente, una matriz de coo podría no boost el uso de la memoria, ya que usará los arreglos provistos como parámetros. Pero cualquier cálculo y / o conversión a csr u otro formato hará copias adicionales.

Me puedo imaginar solucionar los problemas de memoria cargando la base de datos en trozos y usando alguna otra estructura para obtener los valores únicos y la asignación. Incluso podría ser capaz de construir una matriz de coo partir de trozos. Pero tarde o temprano tendrás problemas de memoria. El código scikit hará una o más copias de esa matriz dispersa.