Análisis de dos puntos separados por datos dispersos con pandas y adormecidos

Me gustaría analizar el archivo de datos con el formato col_index: valor en pandas / numpy. Por ejemplo:

0:23 3:41 1:31 2:65

Correspondería a esta matriz:

[[23 0 0 41] [0 31 65 0]]

Parece una forma bastante común de representar datos dispersos en un archivo, pero no puedo encontrar una manera fácil de analizar esto sin tener que hacer algún tipo de iteración después de llamar a read_csv.

Recientemente descubrí que esto es en realidad el formato svm-light y es posible que pueda leer un conjunto de datos como este utilizando un cargador svm como:

http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_svmlight_file.html

Entonces, está analizando el archivo línea por línea una opción, como:

 from scipy.sparse import coo_matrix rows, cols, values = [], [], [] with open('sparse.txt') as f: for i, line in enumerate(f): for cell in line.strip().split(' '): col, value = cell.split(':') rows.append(i) cols.append(int(col)) values.append(int(value)) matrix = coo_matrix((values, (rows, cols))) print matrix.todense() 

¿O necesitas una implementación más rápida en un solo paso? No estoy seguro si esto es posible.

Edición n. ° 1: puede evitar una iteración dividiendo cada línea en un paso utilizando expresiones regulares que conducen a la siguiente implementación alternativa:

 import numpy as np from scipy.sparse import coo_matrix import re rows, cols, values = [], [], [] with open('sparse.txt') as f: for i, line in enumerate(f): numbers = map(int, re.split(':| ', line)) rows.append([i] * (len(numbers) / 2)) cols.append(numbers[::2]) values.append(numbers[1::2]) matrix = coo_matrix((np.array(values).flatten(), (np.array(rows).flatten(), np.array(cols).flatten()))) print matrix.todense() 

Edición # 2: encontré una solución aún más corta sin bucle explícito:

 from scipy.sparse import coo_matrix, vstack def parseLine(line): nums = map(int, line.split(' ')) return coo_matrix((nums[1::2], ([0] * len(nums[0::2]), nums[0::2])), (1, 4)) with open('sparse.txt') as f: lines = f.read().replace(':', ' ').split('\n') cols = max(map(int, " ".join(lines).split(" "))[::2]) M = vstack(map(parseLine, lines)) print M.todense() 

El bucle está oculto dentro de los comandos del map que actúan sobre las lines . Creo que no hay ninguna solución sin bucles en absoluto, ya que la mayoría de las funciones incorporadas las usan y muchos métodos de análisis de re.finditer como re.finditer solo producen iteradores.