2016-07-19 2 views
2

Wie der Titel sagt, versuche ich eine Funktion über jedes Paar von Spalten eines Datenrahmens unter bestimmten Bedingungen anwenden. Ich werde versuchen, das zu veranschaulichen. My df ist von der Form:Pandas: Übernehmen Sie Funktion über jedes Paar von Spalten unter Einschränkungen

Code | 14 | 17 | 19 | ... 
w1 | 0 | 5 | 3 | ... 
w2 | 2 | 5 | 4 | ... 
w3 | 0 | 0 | 5 | ... 

Der Code entspricht eine bestimmte Stelle in einem rechteckigen Gitter und der ws sind verschiedene Worte. Ich würde gerne Cosinus Ähnlichkeitsmaß zwischen jedem Paar von Spalten nur (EDITED!)anwenden, wenn die Summe der Elemente in einer der Spalten des Paares ist größer als 5.

Die gewünschte Ausgabe wäre etwas wie:

 | [14,17] | [14,19] | [14,...] | [17,19] | ... 
Sim |cs(14,17) |cs(14,19) |cs(14,...) |cs(17,19)..| ... 

cs das Ergebnis der Cosinus-Ähnlichkeit für jedes Paar von Spalten ist. Gibt es eine geeignete Methode, dies zu tun?

Jede Hilfe :-)

+0

Wenn ich es gerade bekommen, würden Sie nicht 'cs wollen (14,17)' 'noch cs (14,19)' usw., weil es in der kein Element ist '14' Spalte, die größer als 5 ist. Und hast du irgendwas versucht? Könnten Sie bitte Code und Beispiele angeben, die fehlgeschlagen sind? – danielhadar

+0

Hallo, @danielhadar. Bisher habe ich nur wenige Berechnungen von Hand gemacht. Ich frage, ob es irgendeine Methode gibt, um Funktionen (Kosinusähnlichkeit in diesem Fall, aber ich werde mehr Funktionen anwenden) vektoriell auf jedes Spaltenpaar anzuwenden, d. H. Ohne Schleifen über Spalten zu schreiben. Der Build des letzten df soll nur eine bessere Visualisierung des Ergebnisses haben, aber es ist nicht wichtig. –

Antwort

3

würde geschätzt, um den Cosinus Metrik jedes Paar aus zwei Sammlungen von Eingängen gelten, Sie könnten scipy.spatial.distance.cdist verwenden. Dies wird viel schneller sein als mit einer doppelten Python-Schleife.

Lassen Sie eine Sammlung alle Spalten von df sein. Lassen Sie die andere Sammlung werden nur die Spalten, in denen die Summe größer ist als 5:

import pandas as pd 
df = pd.DataFrame({'14':[0,2,0], '17':[5,5,0], '19':[3,4,5]}) 
mask = df.sum(axis=0) > 5 
df2 = df.loc[:, mask] 

Dann werden die alle Cosinus Ähnlichkeiten mit einem Aufruf zu cdist berechnet werden:

import scipy.spatial.distance as SSD 
values = SSD.cdist(df2.T, df.T, metric='cosine') 
# array([[ 2.92893219e-01, 1.11022302e-16, 3.00000000e-01], 
#  [ 4.34314575e-01, 3.00000000e-01, 1.11022302e-16]]) 

Die Werte können in gewickelt werden ein neuer Datenrahmen und neu gestaltet:

result = pd.DataFrame(values, columns=df.columns, index=df2.columns) 
result = result.stack() 

import pandas as pd 
import scipy.spatial.distance as SSD 
df = pd.DataFrame({'14':[0,2,0], '17':[5,5,0], '19':[3,4,5]}) 
mask = df.sum(axis=0) > 5 
df2 = df.loc[:, mask] 
values = SSD.cdist(df2.T, df.T, metric='cosine') 
result = pd.DataFrame(values, columns=df.columns, index=df2.columns) 
result = result.stack() 
mask = result.index.get_level_values(0) != result.index.get_level_values(1) 
result = result.loc[mask] 
print(result) 

liefert die Serie

17 14 0.292893 
    19 0.300000 
19 14 0.434315 
    17 0.300000 
Verwandte Themen