2015-04-22 8 views
5

Ich habe Daten, die im Format kommt wie folgt:erstellen Adjazenzmatrix in Python von csv-Datensatz

eventid mnbr 
20   1 
26   1 
12   2 
14   2 
15   3 
14   3 
10   3 

eventid ein Ereignis ist, dass das Mitglied die Daten besucht wird als Panel dargestellt, so wie Sie jeder sehen kann Mitglieder nehmen an mehreren Veranstaltungen teil, und mehrere Mitglieder können an derselben Veranstaltung teilnehmen. Mein Ziel ist es, eine Adjazenzmatrix zu erstellen, die zeigt:

mnbr 1 2 3 
1  1 0 0 
2  0 1 1 
3  0 1 1 

, wo es eine 1 ist, wenn zwei Mitglieder der gleichen Veranstaltung teilnehmen. Ich war erfolgreich in der Lage, die Spalten der CSV-Datei in 2 separate 1D-Nummernfelder zu lesen. Ich bin jedoch unsicher, wie es weitergehen soll. Wie erstelle ich am besten eine Matrix mit Spalte 2 und wie verwende ich anschließend Spalte 1, um die Werte einzugeben? Ich verstehe, dass ich keinen Code gepostet habe und keine Lösungen in dieser Hinsicht erwarte, aber ich würde eine Idee schätzen, wie man das Problem auf effiziente Weise angeht. Ich habe ungefähr 3 Millionen Beobachtungen, daher wäre es zu problematisch, zu viele externe Variablen zu erstellen. Danke im Voraus. Ich habe eine Benachrichtigung erhalten, dass meine Frage ein potenzielles Duplikat ist. Mein Problem bestand jedoch darin, die Daten zu analysieren, anstatt die Adjazenzmatrix zu erstellen.

+0

haben Sie eine Schätzung, wie viele einzigartigen Mitglieder und Ereignisse, die du hast? Wenn deine Arrays 'eventid' und' mnbr' heißen, kannst du das mit 'len (set (eventid))' und 'len (set (mnbr))' – Gabriel

+0

auch bestimmen, du brauchst etwas anderes außer a Matrix, um Ihre Ergebnisse zu speichern, da 3 Millionen Quadrat-Integer nicht in den Speicher passen, es sei denn, Sie haben ein paar tausend GB RAM. vielleicht eine karge Matrix oder eine Adjazenzliste. – Gabriel

+0

Entschuldigung, das obige ist falsch, Sie müssen überprüfen, dass 'len (set (mnbr)) ** 2' Ganzzahlen in den Speicher passen, wenn Sie eine Matrix verwenden möchten. – Gabriel

Antwort

4

Hier ist eine Lösung. Es gibt Ihnen nicht direkt die angefragte Adjazenzmatrix, sondern gibt Ihnen das, was Sie benötigen, um es selbst zu erstellen.

#assume you stored every line of your input as a tuples (eventid, mnbr). 
observations = [(20, 1), (26, 1), (12, 2), (14, 2), (15,3), (14, 3), (10, 3)] 

#then creates an event link dictionary. i.e something that link every event to all its mnbrs 
eventLinks = {} 

for (eventid, mnbr) in observations : 
    #If this event have never been encoutered then create a new entry in links 
    if not eventid in eventLinks.keys(): 
     eventLinks[eventid] = [] 

    eventLinks[eventid].append(mnbr) 

#collect the mnbrs 
mnbrs = set([mnbr for (eventid, mnbr) in observations]) 

#create a member link dictionary. This one link a mnbr to other mnbr linked to it. 
mnbrLinks = { mnbr : set() for mnbr in mnbrs } 

for mnbrList in eventLinks.values() : 
    #add for each mnbr all the mnbr implied in the same event. 
    for mnbr in mnbrList: 
     mnbrLinks[mnbr] = mnbrLinks[mnbr].union(set(mnbrList)) 

print(mnbrLinks) 

Ausführen dieses Codes geben das folgende Ergebnis:

{1: {1}, 2: {2, 3}, 3: {2, 3}} 

Dies ist ein Wörterbuch ist, wo jeder mnbrmnbrs einen zugehörigen Satz von adjacency haben. Dies ist tatsächlich eine Adjazenzliste, das ist eine komprimierte Adjazenzmatrix. Sie können sie erweitern und die gewünschte Matrix mit Dictionary-Schlüsseln und -Werten als Zeilen- und Spaltenindizes erstellen.

Ich hoffe, es hilft. Arthur.

EDIT: Ich stellte einen Ansatz mit Adjazenzliste, damit Sie Ihre eigenen Adjazenzmatrix Gebäude implementieren können. Sie sollten jedoch in Betracht ziehen, diese Datenstruktur wirklich zu verwenden, wenn Ihre Daten spärlich sind. Siehe http://en.wikipedia.org/wiki/Adjacency_list

EDIT 2: ein Code hinzufügen adjazenzliste zu einem kleinen Smart adjazenzmatrix

adjacencyList = {1: {1}, 2: {2, 3}, 3: {2, 3}} 

class AdjacencyMatrix(): 

    def __init__(self, adjacencyList, label = ""): 
     """ 
     Instanciation method of the class. 
     Create an adjacency matrix from an adjacencyList. 
     It is supposed that graph vertices are labeled with numbers from 1 to n. 
     """ 

     self.matrix = [] 
     self.label = label 

     #create an empty matrix 
     for i in range(len(adjacencyList.keys())): 
      self.matrix.append([0]*(len(adjacencyList.keys()))) 

     for key in adjacencyList.keys(): 
      for value in adjacencyList[key]: 
       self[key-1][value-1] = 1 

    def __str__(self): 
     # return self.__repr__() is another possibility that just print the list of list 
     # see python doc about difference between __str__ and __repr__ 

     #label first line 
     string = self.label + "\t" 
     for i in range(len(self.matrix)): 
      string += str(i+1) + "\t" 
     string += "\n" 

     #for each matrix line : 
     for row in range(len(self.matrix)): 
      string += str(row+1) + "\t" 
      for column in range(len(self.matrix)): 
       string += str(self[row][column]) + "\t" 
      string += "\n" 


     return string 

    def __repr__(self): 
     return str(self.matrix) 

    def __getitem__(self, index): 
     """ Allow to access matrix element using matrix[index][index] syntax """ 
     return self.matrix.__getitem__(index) 

    def __setitem__(self, index, item): 
     """ Allow to set matrix element using matrix[index][index] = value syntax """ 
     return self.matrix.__setitem__(index, item) 

    def areAdjacent(self, i, j): 
     return self[i-1][j-1] == 1 

m = AdjacencyMatrix(adjacencyList, label="mbr") 
print(m) 
print("m.areAdjacent(1,2) :",m.areAdjacent(1,2)) 
print("m.areAdjacent(2,3) :",m.areAdjacent(2,3)) 

Dieser Code gibt folgendes Ergebnis zu konvertieren:

mbr 1 2 3 
1 1 0 0 
2 0 1 1 
3 0 1 1 

m.areAdjacent(1,2) : False 
m.areAdjacent(2,3) : True 
+0

Vielen Dank für die Hilfe, gibt es trotzdem, um einige der gemeinsamen Adjazenz Visualisierungen direkt aus diesem Wörterbuch zu erstellen? – thyde

+0

Dies ist eine der üblichen Adjazenz Visualisierung;) Aber ja. Ich werde ein Beispiel geben. –