2017-03-03 2 views
1

ich Pandas Datenrahmen von folgendem Format zu erfüllen haben:Was ist der effizienteste Weg, Mathe auf eine Reihe von ausgewählten Zeilen in einem Datenrahmen

Location| X | Y 
---------------- 
A1  | 1 | 2 
A1  | 2 | 3 
A2  | 1 | 1 
A2  | 2 | 3 
etc...many locations...many values 

Ich will bekommen die erste Ableitung in einer für alle Werte Speicherort und verbinden Sie es mit dem ursprünglichen Dataframe als X1.

Location| X | Y | X' 
-------------------- 
A1  | 1 | 2 | 
A1  | 2 | 3 | 
A2  | 1 | 1 | 
A2  | 2 | 3 | 
etc...many locations...many values 

Was ist die effizienteste/eleganteste Methode, dies zu tun? Ich habe einen Ansatz, der so aussieht:

1.) Holen Sie sich alle eindeutigen Standorte.

2.) Durch alle Positionen Iterieren, um nur Zeilen zu erhalten, die mit den Positionen in einer Schleife übereinstimmen.

grad_dict = {} 
for location in locations: 
    selected_rows = df.query('{0} == "{1}") 
    temp_df = np.gradient(selected_rows['X']) 
    grad_dict[location] = temp_df 

3.) verketten alle Wörterbücher zusammen Art wie folgt aus:

result = pd.concat([grad_dict[location] for location in locations]) 

Hinweis: derzeit Es könnte einige kleinere Probleme mit diesem Code sein, wie ich wirklich nicht diesen Wert auf die Datenrahmen Hinzufügen . Aber der weitere Punkt ist meine Frage unten.

Meine Frage: Ist dies der eleganteste/effizienteste Weg? Gibt es einen eleganteren/schnelleren Weg? Wenn es viele Standorte gibt, kann dieser Vorgang manchmal ein paar Sekunden dauern.

Antwort

1

Wenn ich richtig verstehe, sollten Sie in der Lage sein, eine groupby auszuführen und transform verwenden:

df["X'"] = df.groupby('Location')['X'].transform(np.gradient) 

Im Allgemeinen, wenn Sie den gleichen Vorgang auf mehreren Abschnitten eines Datenrahmens durchführen möchten, ist groupby die Art und Weise gehen.

Die resultierende Ausgabe:

Location X Y X' 
0  A1 1 2 1 
1  A1 2 3 1 
2  A2 1 1 1 
3  A2 2 3 1 

bearbeiten

Wenn Sie weitere Argumente np.gradient versorgen wollen, können Sie sie als Argumente an transform liefern. Zum Beispiel:

df["X'"] = df.groupby('Location')['X'].transform(np.gradient, 0.5, edge_order=2) 

Wenn Sie etwas komplexere tun müssen, könnten Sie stattdessen eine Lambda-Funktion angeben, schreiben, was Sie tun wollen, oder eine benutzerdefinierte Funktion separat zu definieren und zu transform passieren. Sie sollten die oben beschriebene Methode verwenden, wenn es möglich ist so, obwohl zu tun, wie ein Lambda-Erstellung wird etwas langsamer:

df["X'"] = df.groupby('Location')['X'].transform(lambda x: np.gradient(x, 0.5, edge_order=2)) 
+0

Heilige Kuh, die schnell ist! Die Antwort kam fast augenblicklich! Ich meine das sowohl für die Frage wie schnell die Frage beantwortet wurde als auch wie schnell der Code ausgeführt wird! Nur eine weitere Frage: Ich habe Schwierigkeiten, Argumente in die Gradientenfunktion einzubringen. Zum Beispiel, wenn ich möchte, dass der Schrittwechsel 0,5 statt 1 ist (Standard) oder wenn ich edge_order = 1 setzen möchte ... wie würde ich das machen? – Thornhale

+0

Nur, um meine eigene Frage zu beantworten: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.GroupBy.transform.html – Thornhale

+0

Bearbeitet, um Ihre Anmerkungen zu adressieren (wie es aussieht, wie Sie dachten schon raus), so haben zukünftige Leser eine in sich geschlossene Antwort. – root

Verwandte Themen