2013-08-06 14 views
26

Ich habe zwei Serien s1 und s2 in Pandas/Python und möchte den Schnittpunkt berechnen, d. H. Wo alle Werte der Serie gemeinsam sind.Den Schnittpunkt zwischen zwei Serien in Pandas finden

Wie würde ich die concat-Funktion verwenden, um dies zu tun? Ich habe versucht, es auszuarbeiten, konnte es aber nicht (ich will den Schnittpunkt nicht auf den Indizes von S1 und S2 berechnen, sondern auf den Werten).

Vielen Dank im Voraus.

Antwort

28

Platzieren Sie beide Serien im Python-Set-Container. Siehe Dokumentation: http://docs.python.org/2/library/sets.html

Verwenden Sie dann die Schnittmengenmethode.

s1.intersection (s2) und dann bei Bedarf in die Liste zurücktransformieren.

Gerade bemerkte Pandas im Tag. Kann das zurück übersetzen.

pd.Series(list(set(s1).intersection(set(s2)))) 

von Kommentaren Ich habe dies zu einem pythonic Ausdruck verändert, was zu lesen kürzer und einfacher ist:

Series(list(set(s1) & set(s2))) 

sollte den Trick, mit der Ausnahme, wenn die Indexdaten für Sie auch wichtig ist

Habe die Liste (....) hinzugefügt, um den Satz zu übersetzen, bevor du zur pd.Series gelangst. Pandas akzeptiert keinen Satz als direkte Eingabe für eine Serie.

+1

auch, können Sie '&' Operator für Schnittmenge verwenden. –

+0

Eigentlich kann man nicht einfach Serie auf ein Set anwenden (was nervt) 'TypeError: Set-Wert ist ungeordnet', scheint unnötige Einschränkung/nicht sehr Ente. –

+0

Mmm.habe die gleiche Logik vorhin benutzt, aber wahrscheinlich habe ich sie auf die Liste 1 gesetzt ... kurz calc, also war die Performance keine große Einschränkung. Wie lautet die Syntax für die Verwendung des Operators &, um das Set zu erstellen? – Joop

9

Wenn Sie Panda verwenden, nehme ich an, dass Sie auch NumPy verwenden. Numpy hat eine Funktion intersect1d, die mit einer Pandas-Serie funktioniert.

Beispiel:

pd.Series(np.intersect1d(pd.Series([1,2,3,5,42]), pd.Series([4,5,6,20,42]))) 

wird eine Reihe mit den Werten zurückkehren 5 und 42

+1

FYI Das ist Größenordnungen langsamer als festgelegt. :( –

+0

Für Schande. @AndyHayden Gibt es einen Grund, warum wir keine Set-Ops zu "Series" -Objekten hinzufügen können? –

+0

Danke, @AndyHayden. Ich hatte nur naiv angenommen, dass numpy schnellere Ops auf Arrays hätte. Ein schneller '% Zeit' Test zeigt, dass Sie _mostly_ correct. Meine Methode hatte einen Durchschnitt von 775 us pro Schleife auf zwei Serien von 100 zufällig generierten Elementen, während @ Joop-Methode 120 us pro Schleife hatte.Aber für größere Datensätze ist diese Beziehung umgekehrt Sätze von 100000 Elementen, zeigte meine Methode 1,32 ms pro Schleife und @ Joop-Methode zeigte 14,9 ms pro Schleife. – jbn

14

Setup:

s1 = pd.Series([4,5,6,20,42]) 
s2 = pd.Series([1,2,3,5,42]) 

Timings:

%%timeit 
pd.Series(list(set(s1).intersection(set(s2)))) 
10000 loops, best of 3: 57.7 µs per loop 

%%timeit 
pd.Series(np.intersect1d(s1,s2)) 
1000 loops, best of 3: 659 µs per loop 

%%timeit 
pd.Series(np.intersect1d(s1.values,s2.values)) 
10000 loops, best of 3: 64.7 µs per loop 

So ist die numpy Lösung kann vergleichbar sein zur eingestellten Lösung auch für kleine Serien, wenn man die values explizit verwendet.

+4

redid test mit neustem numpy (1.8.1) und pandas (0.14.1) sieht aus wie dein zweites Beispiel ist jetzt in timeing vergleichbar Andere. Bei größeren Daten ist Ihre letzte Methode ein klarer Gewinner 3 mal schneller als andere – Joop

+0

Gut zu wissen, danke für das Update! –

5

Python

s1 = pd.Series([4,5,6,20,42]) 
s2 = pd.Series([1,2,3,5,42]) 

s1[s1.isin(s2)] 

R

s1 <- c(4,5,6,20,42) 
s2 <- c(1,2,3,5,42) 

s1[s1 %in% s2] 

Edit: Nicht Betrogenen behandeln.

+2

Es wird nicht richtig behandelt Duplikate, zumindest der R-Code, nicht über Python. In R gibt es eine 'intersect'-Funktion und für data.frame/data.table' fintersect'. – jangorecki

2

konnte Merge-Operator wie folgt

pd.merge(df1, df2, how='inner') 
+0

Aber die Reihe muss in Datenrahmen umgewandelt werden, bevor man 'pd.merge' verwenden kann – keshr3106

Verwandte Themen