2017-02-02 5 views
2

Ich habe 2 Pandas Datenrahmen, die ungleich lang sind. Ich habe ein Beispiel unten zitiert. Mein Code sollte durch den Wert von Äpfeln im 1. Datenrahmen laufen und lokalisieren, ob es im zweiten Datenrahmen existiert (es wird immer einen Wert geben, der im 2. Datenrahmen existiert). Wenn es denselben Wert findet, sollte es die Differenz von Orangen in den 2 Datenrahmen in den ersten Datenrahmen speichern. Ich habe diese Aufgabe mit 2 for loops durchgeführt, die auch unten angegeben sind. Der folgende Code erledigt die Aufgabe, aber meine tatsächlichen Daten haben 2 Millionen Einträge und der zweite Datenrahmen hat 800 Einträge. Die Verwendung von 2 For-Loops verlangsamt mein Programm erheblich. Gibt es eine effizientere Möglichkeit, diese Aufgabe zu erledigen?Identifizieren ähnlicher Werte durch Iterieren zwischen zwei Pandas-Datenrahmen.

trial={'apples': [2,4,1,5,3,2,1,1,4,5],'oranges': [8,5,9,4,2,6,7,5,1,3]} 
trial1={'apples': [1,2,3,4,5],'oranges': [2,5,6,3,1]} 
df=pd.DataFrame.from_dict(trial) 
df1=pd.DataFrame.from_dict(trial1) 
F=[] 
for i in df.apples.index: 
    for j in df1.apples.index: 
     if df.apples.ix[i]== df1.apples.ix[j]: 
      F.append(df.oranges.ix[i]-df1.oranges.ix[j])     
df['difference']=F 

Antwort

2

Sie können einen linken Typ merge auf der Äpfel Spalte ausführen zu können, dann diff auf den kollidierenden Spalten aufrufen können orange_x und orange_y, und dann das Vorzeichen umkehren - und gegossen zu int mit astype mit:

In [159]: 
df['difference'] = -df.merge(df1, on='apples', how='left').ix[:, 'oranges_x':].diff(axis=1)['oranges_y'].astype(int) 
df 

Out[159]: 
    apples oranges difference 
0  2  8   3 
1  4  5   2 
2  1  9   7 
3  5  4   3 
4  3  2   -4 
5  2  6   1 
6  1  7   5 
7  1  5   3 
8  4  1   -2 
9  5  3   2 

brechen des oben nach unten:

In [162]: 
df.merge(df1, on='apples', how='left') 

Out[162]: 
    apples oranges_x oranges_y 
0  2   8   5 
1  4   5   3 
2  1   9   2 
3  5   4   1 
4  3   2   6 
5  2   6   5 
6  1   7   2 
7  1   5   2 
8  4   1   3 
9  5   3   1 

In [163]: 
df.merge(df1, on='apples', how='left').ix[:, 'oranges_x':].diff(axis=1) 

Out[163]: 
    oranges_x oranges_y 
0  NaN  -3.0 
1  NaN  -2.0 
2  NaN  -7.0 
3  NaN  -3.0 
4  NaN  4.0 
5  NaN  -1.0 
6  NaN  -5.0 
7  NaN  -3.0 
8  NaN  2.0 
9  NaN  -2.0 

In [164]: 
-df.merge(df1, on='apples', how='left').ix[:, 'oranges_x':].diff(axis=1)['oranges_y'].astype(int) 

Out[164]: 
0 3 
1 2 
2 7 
3 3 
4 -4 
5 1 
6 5 
7 3 
8 -2 
9 2 
Name: oranges_y, dtype: int32 

Wenn Ihre realen Daten mehr Spalten hat, können Sie diese in separaten Schritten tun, wenn die Spalte, um aus Ihrem Beispiel unterscheidet:

In [170]: 
merged = df.merge(df1, on='apples', how='left') 
merged['difference'] = merged['oranges_x'] - merged['oranges_y'] 
merged 

Out[170]: 
    apples oranges_x oranges_y difference 
0  2   8   5   3 
1  4   5   3   2 
2  1   9   2   7 
3  5   4   1   3 
4  3   2   6   -4 
5  2   6   5   1 
6  1   7   2   5 
7  1   5   2   3 
8  4   1   3   -2 
9  5   3   1   2 

So nach dem Zusammenführen, die irrelevanten Spalten löschen und umbenennen zurück:

In [171]:  
merged = merged.drop('oranges_y', axis=1).rename(columns={'oranges_x':'oranges'}) 
merged 

Out[171]: 
    apples oranges difference 
0  2  8   3 
1  4  5   2 
2  1  9   7 
3  5  4   3 
4  3  2   -4 
5  2  6   1 
6  1  7   5 
7  1  5   3 
8  4  1   -2 
9  5  3   2 
+0

Danke vielmals. Genau das habe ich gesucht. –

+0

Sie können meine Antwort akzeptieren, wenn es Ihre Frage gelöst hat, wird oben links in meiner Antwort ein leeres Häkchen angezeigt, damit die Frage nicht unbeantwortet bleibt. – EdChum

+0

Hallo, es funktioniert. Aber für meine Daten ist der Unterschied für alle Spalten nan. Ich kann jedoch sehen, dass es in den 2 Datenrahmen übereinstimmende Werte gibt. Die 2-for-Loop-Methode funktioniert und gibt Ergebnisse. –

Verwandte Themen