2017-11-13 3 views
1

habe ich eine sparse.txt, die wie folgt aussieht: diese erstellen dichte Matrix aus Sparse Matrix efficently (numpy/scipy aber NO sklearn)

Die erforderliche dense.txt ist

# first column is label 0 or 1 
# rest of the data is sparse data 
# maximum value in the data is 4, so the future dense matrix will 
# have 1+4 = 5 elements in a row 
# file: sparse.txt 
1 1:1 2:1 3:1 
0 1:1 4:1 
1 2:1 3:1 4:1 
:

# required file: dense.txt 
1 1 1 1 0 
0 1 0 0 1 
1 0 1 1 1 

Ohne scipy coo_matrix mit ihm tat es auf einfache Weise wie folgt aus:

def create_dense(fsparse, fdense,fvocab): 
    # number of lines in vocab 
    lvocab = sum(1 for line in open(fvocab)) 

    # create dense file 
    with open(fsparse) as fi, open(fdense,'w') as fo: 
     for i, line in enumerate(fi): 
      words = line.strip('\n').split(':') 
      words = " ".join(words).split() 

      label = int(words[0]) 
      indices = [int(w) for (i,w) in enumerate(words) if int(i)%2] 

      row = [0]* (lvocab+1) 
      row[0] = label 

      # use listcomps 
      row = [ 1 if i in indices else row[i] for i in range(len(row))] 

      l = " ".join(map(str,row)) + "\n" 
      fo.write(l) 

      print('Writing dense matrix line: ', i+1) 

Frage Wie können wir direkt Label und Daten aus spärlichen Daten erhalten, ohne vorher eine dichte Matrix zu erstellen und NUMPY/Scipy zu verwenden?

Frage: Wie können wir die spärlichen Daten mit numpy.fromregex lesen?

Mein Versuch ist:

def read_file(fsparse): 
    regex = r'([0-1]\s)([0-9]):(1\s)*([0-9]:1)' + r'\s*\n' 
    data = np.fromregex(fsparse,regex,dtype=str) 

    print(data,file=open('dense.txt','w')) 

Es hat nicht funktioniert!

Weiterführende Links:

Parsing colon separated sparse data with pandas and numpy

+0

Wie wäre es mit 'row' in einer Liste? Das wäre eine Liste von Listen (von Zahlen), oder? Können Sie das Array direkt daraus machen? – hpaulj

+0

@hpaulj, ich kann Array von Etiketten machen, aber Schwierigkeiten haben, Matrix. – astro123

+0

@hpauj, ich kann auch Label lesen, und Daten aus einer Textdatei mit numpy.loadtxt, – astro123

Antwort

3

Code Tweaking die dichte Anordnung direkt über Datei, sondern zu erstellen:

fsparse = 'stack47266965.txt' 

def create_dense(fsparse, fdense, lvocab):  
    alist = [] 
    with open(fsparse) as fi: 
     for i, line in enumerate(fi): 
      words = line.strip('\n').split(':') 
      words = " ".join(words).split() 

      label = int(words[0]) 
      indices = [int(w) for (i,w) in enumerate(words) if int(i)%2] 

      row = [0]* (lvocab+1) 
      row[0] = label 

      # use listcomps 
      row = [ 1 if i in indices else row[i] for i in range(len(row))] 
      alist.append(row) 
    return alist 

alist = create_dense(fsparse, fdense, 4) 
print(alist) 
import numpy as np 
arr = np.array(alist) 
from scipy import sparse 
M = sparse.coo_matrix(arr) 
print(M) 
print(M.A) 

produziert

0926:~/mypy$ python3 stack47266965.py 
[[1, 1, 1, 1, 0], [0, 1, 0, 0, 1], [1, 0, 1, 1, 1]] 
    (0, 0) 1 
    (0, 1) 1 
    (0, 2) 1 
    (0, 3) 1 
    (1, 1) 1 
    (1, 4) 1 
    (2, 0) 1 
    (2, 2) 1 
    (2, 3) 1 
    (2, 4) 1 
[[1 1 1 1 0] 
[0 1 0 0 1] 
[1 0 1 1 1]] 

Wenn Sie überspringen möchten das dichte arr, müssen Sie das Äquivalent der M.row, M.col und M.data Attribute erzeugen (Reihenfolge spielt keine Rolle)

[0 0 0 0 1 1 2 2 2 2] 
[0 1 2 3 1 4 0 2 3 4] 
[1 1 1 1 1 1 1 1 1 1] 

Ich regex nicht viel verwenden, so werde ich nicht versuchen, das zu beheben. Ich nehme an, Sie

'1 1:1 2:1 3:1' 

in

['1' '1' '2' '2' '1' '3' '1'] 

konvertieren möchten Aber das bekommt man nur auf die words/label Bühne.


A direkt zu spärlich:

def create_sparse(fsparse, lvocab): 

    row, col, data = [],[],[] 
    with open(fsparse) as fi: 
     for i, line in enumerate(fi): 
      words = line.strip('\n').split(':') 
      words = " ".join(words).split() 

      label = int(words[0]) 
      row.append(i); col.append(0); data.append(label) 

      indices = [int(w) for (i,w) in enumerate(words) if int(i)%2] 
      for j in indices: # quick-n-dirty version 
       row.append(i); col.append(j); data.append(1) 
    return row, col, data 

r,c,d = create_sparse(fsparse, 4) 
print(r,c,d) 
M = sparse.coo_matrix((d,(r,c))) 
print(M) 
print(M.A) 

[0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2] [0, 1, 2, 3, 0, 1, 4, 0, 2, 3, 4] [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1] 
.... 

Das einzige, was produzieren, die anders ist, der mit dem Wert eines data Artikel ist 0. sparse wird sich darum kümmern.

+0

FANTASTISCH !! Genau das habe ich gesucht. – astro123

3

(Beantwortet vor ausdrücklich disallowing sklearn)

Dies ist im Grunde die svmlight/libsvm format.

Verwenden Sie einfach scikit-learn'sload_svmlight_file oder die effizientere svmlight-loader. Keine Notwendigkeit, das Rad hier neu zu erfinden!

from sklearn.datasets import load_svmlight_file 

X, y = load_svmlight_file('C:/TEMP/sparse.txt') 
print(X) 
print(y) 
print(X.todense()) 

Ausgang:

(0, 0)  1.0 
(0, 1)  1.0 
(0, 2)  1.0 
(1, 0)  1.0 
(1, 3)  1.0 
(2, 1)  1.0 
(2, 2)  1.0 
(2, 3)  1.0 
[ 1. 0. 1.] 
[[ 1. 1. 1. 0.] 
[ 1. 0. 0. 1.] 
[ 0. 1. 1. 1.]] 
+0

Vielen Dank, aber ich werde wirklich zu schätzen wissen, wenn wir tun könnten mit numpy/scipy und ohne sciki-learn. Ich versuche einen Weg zu finden, es mit numpy/scipy.Solving ist nicht das Problem, ich habe einen Weg gefunden, dichte.txt ineffizient wie oben angegeben zu finden. – astro123

+0

Lesen Sie [ihren Code und verwenden Sie es] (https://github.com/scikit-learn/scikit-learn/blob/f3320a6f/sklearn/datasets/svmlight_format.py). Was stimmt damit nicht? Der schnellere externe könnte auch leichter zu zerlegen sein (oops; wahrscheinlich Cython-basiert ...). Sie sagen also, dass dies eine Lernerfahrung ist und nicht über den realen Gebrauch? – sascha

+0

Es tut mir leid für die Verwirrung Dr. Sascha, hier in dieser Frage lerne ich einen Weg zu verwenden numpy/scipy, um diese Aufgabe zu tun und sklearn ist zu weit fortgeschritten und aus der Blackbox. – astro123

Verwandte Themen