2016-03-27 5 views
0

Ich versuche, eine nearest neighbors Sache zu machen, die super super schnell ist. Im Moment benutze ich networkx dann Iterieren durch alle G.nodes() dann S = set(G.neighbors(node)) dann S.remove(node), die ziemlich gut funktioniert, aber ich möchte besser bei der Indexierung und Nutzung von Datenstrukturen. Ich möchte mich von der Iteration entfernen, wenn es möglich ist.np.where auf pd.DataFrame für Wörterbuch von Nicht-Null-Indices

ich schließlich von oben mit einem Dictionary-Objekt beenden möge, wo Schlüssel root_node und Wert ist ein Satz von Knoten Nachbarn (nicht dem root_node einschließlich)

Hier ist, was meine Graph und DF_adj Adjazenzmatrix wie folgt aussehen: enter image description here

Wenn ich np.where(DF_adj == 1) tun die Ausgabe 2-Arrays, die wie folgt aussieht:

(array([ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 
     3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 
     8, 9, 9, 10, 10]), array([ 0, 1, 3, 4, 5, 7, 0, 1, 2, 3, 4, 6, 8, 9, 10, 1, 2, 
     0, 1, 3, 0, 1, 4, 0, 5, 6, 1, 5, 6, 0, 7, 8, 1, 7, 
     8, 1, 9, 1, 10])) 

diese Option aktiviert, aber es hat mich nicht ganz Python pandas: select columns with all zero entries in dataframe

def neighbors(DF_adj): 
    D_node_neighbors = defaultdict(set) 
    DF_indexer = DF_adj.fillna(False).astype(bool) #Don't need this for my matrix but could be useful for non-binary matrices if someones needs it 
    for node in DF_adj.columns: 
     D_node_neighbors[node] = set(DF_adj.index[np.where(DF_adj[node] == 1)]) 
     D_node_neighbors[node].remove(node) 
    return(D_node_neighbors) 

helfen Wie kann ich np.where auf dem gesamten pd.DataFrame nutzen diese Art der Ausgabe zu erhalten?

defaultdict(set, 
      {'a': {'b', 'd', 'e', 'f', 'h'}, 
      'b': {'a', 'c', 'd', 'e', 'g', 'i', 'j', 'k'}, 
      'c': {'b'}, 
      'd': {'a', 'b'}, 
      'e': {'a', 'b'}, 
      'f': {'a', 'g'}, 
      'g': {'b', 'f'}, 
      'h': {'a', 'i'}, 
      'i': {'b', 'h'}, 
      'j': {'b'}, 
      'k': {'b'}}) 
+0

Sie können nicht, 'np.where()' ist nicht gonna Rückkehr ein Wörterbuch. – Goyo

+0

Ich weiß, aber es könnte eine effizientere Möglichkeit, dass ich denke dann durch alle Spalten einzeln durchlaufen –

Antwort

1

Sie können es mit Verständnis dict tun. Wenn df ist:

a b c d e f g h i j k 
a 1 1 0 1 1 1 0 1 0 0 0 
b 1 1 1 1 1 0 1 0 1 1 1 
c 0 1 1 0 0 0 0 0 0 0 0 
d 1 1 0 1 0 0 0 0 0 0 0 
e 1 1 0 0 1 0 0 0 0 0 0 
f 1 0 0 0 0 1 1 0 0 0 0 
g 0 1 0 0 0 1 1 0 0 0 0 
h 1 0 0 0 0 0 0 1 1 0 0 
i 0 1 0 0 0 0 0 1 1 0 0 
j 0 1 0 0 0 0 0 0 0 1 0 
k 0 1 0 0 0 0 0 0 0 0 1 

Dann {i:{ j for j in df.index if df.ix[i,j] and i!= j} for i in df.index } ist:

{'j': {'b'}, 
'e': {'a', 'b'}, 
'g': {'b', 'f'}, 
'k': {'b'}, 
'a': {'b', 'd', 'e', 'f', 'h'}, 
'c': {'b'}, 
'i': {'b', 'h'}, 
'f': {'a', 'g'}, 
'b': {'a', 'c', 'd', 'e', 'g', 'i', 'j', 'k'}, 
'd': {'a', 'b'}, 
'h': {'a', 'i'}} 

oder 2x schneller:

s=df.index   
d=collections.defaultdict(set) 
for (k,v) in zip(*where(df==1)): 
    if k!=v: 
     d[s[k]].add(s[v]) 
+0

'1 Schleife, das Beste von 3: 4,75 s pro Schleife 1 Schleife, das Beste von 3: 2,41 s pro Schleife auf meinem schnellsten (dem nx.graph) war dein doppelt so schnell. Danke Mann, das ist wirklich hilfreich –

Verwandte Themen