2017-02-01 4 views
0

Ich versuche, die Anzahl der Netzkanten von einer normalisierten SQLite-Datenbank zu erhalten, die wie folgt normalisiert wurde:Erhalten Netzwerk Kanten von SQL-Tabellen für NetworkX in Python

Authors     Paper      Paper_Authors 
| authorID | name | etc | paperID | title | etc | paperID | authorID | 
| 1  | .... | ... | 1 | ..... | ... | 1  | 1  | 
| 2  | .... | ... | 2 | ..... | ... | 1  | 2  | 
| 3  | .... | ... | . | ..... | ... | 1  | 3  | 
| 4  | .... | ... | 60,000 | ..... | ... | 2  | 1  | 
| 5  | .... | ...        | 2  | 4  | 
| .  | .... | ...        | 2  | 5  | 
| 120,000 | .... | ...        | .  | .  | 
                 | 60,000 | 120,000 | 

Mit irgendwo in der Region von 120.000 Autoren und 60.000 Papiere, und die Indextabelle hat ungefähr 250.000 Reihen.

Ich versuche, dies in NetworkX zu bekommen einige Konnektivität Analyse zu tun, um die Knoten Eingabe ist einfach:

conn = sqlite3.connect('../input/database.sqlite') 
c = conn.cursor() 
g = nx.Graph() 
c.execute('SELECT authorID FROM Authors;') 
authors = c.fetchall() 
g.add_nodes_from(authors) 

Das Problem, das ich entsteht habe von dem Versuch, die Kanten zu bestimmen, zu NetworkX zu füttern, die erfordert die Werte in einem Tupel der zwei zu verbindenden Knoten unter Verwendung der obigen Daten als ein Beispiel;

[(1,1),(1,2),(1,3),(2,3),(1,4),(1,5),(4,5)] 

Würde den obigen Datensatz beschreiben.

Ich habe den folgenden Code, der funktioniert, aber ist unelegant:

def coauthors(pID): 
    c.execute('SELECT authorID \ 
       FROM Paper_Authors \ 
       WHERE paperID IS ?;', (pID,)) 
    out = c.fetchall() 
    g.add_edges_from(itertools.product(out, out)) 

c.execute('SELECT COUNT() FROM Papers;') 
papers = c.fetchall() 

for i in range(1, papers[0][0]+1): 
    if i % 1000 == 0: 
     print('On record:', str(i)) 
    coauthors(i) 

Dies funktioniert, indem in der Datenbank durch jedes der Papiere Looping, eine Liste der Autoren Rückkehr und iterativ machen Liste der Autor Kombination Tupeln und das Hinzufügen von ihnen mit dem Netzwerk in Teilen, die funktionieren, aber dauerte 30 - 45 Minute:

print(nx.info(g)) 
Name: 
Type: Graph 
Number of nodes: 120670 
Number of edges: 697389 
Average degree: 11.5586 

Also meine Frage ist, gibt es eine elegantere Möglichkeit zum gleichen Ergebnis zu kommen, idealerweise mit dem paperID als Kantenbeschriftung, um die Navigation zu erleichtern das Netzwerk außerhalb von NetzwerkX.

+0

Ist das Netzwerk nicht direkt durch die Zeilen in 'Paper_Authors' definiert? Wie verhält es sich mit der Tupel-Liste, die Sie zu den Beispieldaten anzeigen? –

+0

@ CL. leider nicht, da networkx anscheinend das Tupel benötigt, das die Kante im Format 'edge = (node, node) 'definiert, also in diesem Fall' paper = (author, author) ', was die' Paper_Authors' Daten verwenden würde sei im Format "edge = (author, paper)", es sei denn, es gibt eine Möglichkeit, 2 Arten von Knoten zu definieren und dann das Netzwerk irgendwie zu reduzieren. –

+0

@ CL. Ich habe das ein wenig genauer untersucht, und es funktioniert, wenn ich den Autoren und Papieren ein anderes Präfix gebe und im Wesentlichen zwei verschiedene Arten von Knoten habe, einen für die Papiere und einen für die Autoren. –

Antwort

2

Sie können alle Kombinationen von Autoren für jedes Papier mit einem selbst erhalten beitreten:

SELECT paperID, 
     a1.authorID AS author1, 
     a2.authorID AS author2 
FROM Paper_Authors AS a1 
JOIN Paper_Authors AS a2 USING (paperID) 
WHERE a1.authorID < a2.authorID;   -- prevent duplicate edges 

Diese schrecklich ineffizient sein wird, wenn Sie einen Index für paperID, oder besser, eine sowohl covering index auf paperID und authorID, oder besser, ein WITHOUT ROWID table.

+0

Vielen Dank, das hat perfekt funktioniert und dauerte nur ungefähr 2 Sekunden in ungefähr 600.000 Ausgangsreihen, ich werde mir auch die anderen Beschleunigungen ansehen. Vielen Dank für die Antwort, das Problem, das ich mit meinem Denken hatte, war, wie kann ich die authorID auswählen, wenn ich bereits die authorID auswähle. –

Verwandte Themen