2016-03-24 13 views
1

Durchführen einer Mahalanobis-Berechnung für jede Zeile eines DataFrame mit Abständen zu jeder anderen Zeile im DataFrame. Es sieht ein bisschen wie folgt aus:Python & Pandas: Iterieren zweimal über DataFrame

import pandas as pd 
from scipy import linalg 
from scipy.spatial.distance import mahalanobis 
from pprint import pprint 

testa = { 'pid': 'testa', 'a': 25, 'b': .455, 'c': .375 } 
testb = { 'pid': 'testb', 'a': 22, 'b': .422, 'c': .402 } 
testc = { 'pid': 'testc', 'a': 11, 'b': .389, 'c': .391 } 

cats = ['a','b','c'] 
pids = pd.DataFrame([ testa, testb, testc ]) 
inverse = linalg.inv(pids[cats].cov().values) 
distances = { pid: {} for pid in pids['pid'].tolist() } 

for i, p in pids.iterrows(): 
    pid = p['pid'] 
    others = pids.loc[pids['pid'] != pid] 
    for x, other in others.iterrows(): 
     otherpid = other['pid'] 
     d = mahalanobis(p[cats], other[cats], inverse) ** 2 
     distances[pid][otherpid] = d 

pprint(distances) 

es für die drei Testfälle hier gut funktioniert, aber im wirklichen Leben, es wird gegen rund um 2000-3000 Reihen laufen, und mit diesem Ansatz zu lange dauert. Ich bin relativ neu in Pandas und ich bevorzuge wirklich Python zu R, also möchte ich das gereinigt haben.

Wie kann ich das effizienter machen?

+1

Warum nicht [ 'scipy.spatial.distance.pdist'] (http://docs.scipy.org/doc/scipy-0.16.0/reference/generated /scipy.spatial.distance.pdist.html) um die paarweisen Abstände zu berechnen? Es akzeptiert ein "metrisches" Argument von "Mahalanobis". – ChrisP

+0

Wissen Sie, ob es einen großen Unterschied zwischen 'scipy.spatial.distance.pdist' und dem von' sklearn' gibt, der unten erwähnt wird? Scheint wie derselbe Ansatz, nicht? – Wells

Antwort

1

Durchführen einer Mahalanobis-Berechnung für jede Zeile eines DataFrame mit Abständen zu jeder anderen Zeile im DataFrame.

Dies ist im Wesentlichen in sklearn.metrics.pairwise.pairwise_distances adressiert, so ist es zweifelhaft, ob es möglich ist, es effizienter per Hand zu tun. In diesem Fall wird daher, wie etwa

from sklearn import metrics 

>>> metrics.pairwise.pairwise_distances(
    pids[['a', 'b', 'c']].as_matrix(), 
    metric='mahalanobis') 
array([[ 0.  , 2.15290501, 3.54499647], 
     [ 2.15290501, 0.  , 2.62516666], 
     [ 3.54499647, 2.62516666, 0.  ]]) 
+0

Whoa, werde ich einen Schuss geben. – Wells

+0

woher weiß ich, was in dem resultierenden Array ist? Meine Hacky-Lösung ermöglicht mir den Zugriff auf den "pid" -Wert, der eine Kennung für die Comp ist. – Wells

Verwandte Themen