2016-06-21 15 views
0

Mit Daten arbeiten und eine spärliche Matrix erstellen, die später für Clusterzwecke verwendet wird.Sparse-Matrix in Python erstellen

fileHandle = open('data', 'r') 

for line in fileHandle: 
    json_list = [] 
    fields = line.split('\t') 
    json_list.append(fields[0]) 
    json_list.append(fields[1]) 
    json_list.append(fields[3]) 

Gerade jetzt die Daten wie folgt aussieht:

term, ids, quantity 
['buick', '123,234', '500'] 
['chevy', '345,456', '300'] 
['suv','123', '100'] 

Der Ausgang ich so wäre müssten:

mit numpy Sparse Matrix Bibliothek
term, quantity, '123', '234', '345', '456', '567' 
buick, 500, 1, 1, 0, 0, 0 
chevy, 300, 0, 0, 1, 1, 0 
suv, 100, 1, 0, 0, 0, 0 

Ich habe versucht, arbeiten aber ohne Erfolg.

+0

In welchem ​​Format haben Sie die Eingabe (n)? Können Sie Code auflisten, der diese Beispieldaten reproduzieren würde? – Divakar

+0

@Divakar hinzugefügt, vielen Dank für Ihre Frage – jKraut

+0

Würden 'ids' immer paarweise kommen? Wenn ja, können Sie es in zwei Spalten aufteilen? Das könnte einfacher zu verarbeiten sein. – Divakar

Antwort

0

scikit_learn wahrscheinlich die Werkzeuge, dies leicht zu tun hat, aber ich werde eine grundlegende Python/numpy Lösung demonstrieren.

Die Rohdaten - eine Liste von Listen

In [1150]: data=[['buick', '123,234', '500'], 
       ['chevy', '345,456', '300'], 
       ['suv','123', '100']] 

I bewandert Spalten mit Listenkomprehensionen herausziehen kann. Dies ist vielleicht nicht die schnellste in einem sehr großen Fall, aber im Moment ist es eine einfache Möglichkeit, das Problem Stück für Stück anzugehen.

In [1151]: terms=[row[0] for row in data] 

In [1152]: terms 
Out[1152]: ['buick', 'chevy', 'suv'] 

In [1153]: quantities=[int(row[2]) for row in data] 

In [1154]: quantities 
Out[1154]: [500, 300, 100] 

Erstellen Sie die Liste der möglichen IDs. Ich könnte diese von data ziehen, aber Sie verwenden anscheinend eine größere Liste. Sie könnten Strings statt Ints sein.

In [1155]: idset=[123,234,345,456,567] 

In [1156]: ids=[[int(i) for i in row[1].split(',')] for row in data] 

In [1157]: ids 
Out[1157]: [[123, 234], [345, 456], [123]] 

np.in1d ist ein praktisches Werkzeug für die Suche nach, wo diese Teil-Listen in der Master-Liste passen. Die resultierende idM ist die Feature-Matrix, mit vielen Nullen und ein paar.

In [1158]: idM=np.array([np.in1d(idset,i) for i in ids],int) 

In [1159]: idM 
Out[1159]: 
array([[1, 1, 0, 0, 0], 
     [0, 0, 1, 1, 0], 
     [1, 0, 0, 0, 0]]) 

Wir könnten die Stücke auf verschiedene Arten zusammenbauen.

In [1161]: M=np.zeros(len(data),dtype='U10,int,(5)int') 

In [1162]: M['f0']=terms 

In [1163]: M['f1']=quantities 

In [1164]: M['f2']=idM 

In [1165]: M 
Out[1165]: 
array([('buick', 500, [1, 1, 0, 0, 0]), ('chevy', 300, [0, 0, 1, 1, 0]), 
     ('suv', 100, [1, 0, 0, 0, 0])], 
     dtype=[('f0', '<U10'), ('f1', '<i4'), ('f2', '<i4', (5,))]) 

idM drehte sich mit in einer Sparse-Matrix könnte:

Zum Beispiel könnte eine strukturierte Anordnung mit erstellenden

In [1167]: from scipy import sparse 

In [1168]: c=sparse.coo_matrix(idM) 

In [1169]: c 
Out[1169]: 
<3x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 5 stored elements in COOrdinate format> 

In [1170]: c.A 
Out[1170]: 
array([[1, 1, 0, 0, 0], 
     [0, 0, 1, 1, 0], 
     [1, 0, 0, 0, 0]]) 

war es einfacher, zuerst in dieser Erforschung der dichteren Array zu erstellen , und machen Sie davon spärlich.

Aber sparse bietet eine bmat Funktion, mit der ich die MultiRow-Matrix aus einer Liste von einzelnen Zeilen erstellen kann. (Siehe meine Versionsgeschichte für eine Version, die die coo Eingänge direkt Konstrukte)

In [1220]: ll=[[sparse.coo_matrix(np.in1d(idset,i),dtype=int)] for i in ids] 

In [1221]: sparse.bmat(ll) 
Out[1221]: 
<3x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 5 stored elements in COOrdinate format> 

In [1222]: sparse.bmat(ll).A 
Out[1222]: 
array([[1, 1, 0, 0, 0], 
     [0, 0, 1, 1, 0], 
     [1, 0, 0, 0, 0]], dtype=int32) 
+0

unklar auf 1158, wo Sie "idset" in IDM = np.array bekommen haben ([np.in1d ​​(idset, i) für i in ids], int) – jKraut

+0

Identisch mit 'idlist' in [1155]. Ich habe beide Namen definiert, habe aber 'idset' verwendet. Ich habe die Werte von Ihrer gewünschten Ausgabetabelle erhalten. – hpaulj

0

Ich habe einen faulen Methode

data = [['term', 'ids', 'quantity'], 
... ['buick', ['123', '234'], 500], 
... ['chevy', ['345', '456'], 300], 
... ['suv', ['123', '567'], 100]] 
res = [] 
for i,line in enumerate(data): 
...  if i == 0: 
...   header = line 
...  else: 
...   temp = {} 
...   for j,ele in enumerate(line): 
...    if j in [0,2]: 
...     temp.update({header[j] : ele}) 
...    else: 
...     for num in line[1]: 
...      temp.update({ num:1 }) 
...   res.append(temp) 

with open(filepath,'wb') as f: 
...  w = csv.DictWriter(f,set([ k for ele in res for k in ele.keys()])) 
...  w.writeheader() 
...  w.writerows(res) 

Ausgang

term 456 567 345 123 234 quantity 
buick    1 1 500 
chevy 1  1   300 
suv  1  1   100