Seite 1 von 1

lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 09:31
von C#17
Hallo liebes Forum,

ich habe ein pandas DataFrame welcher wie folgt ausschaut.:

Code: Alles auswählen

   key  data1  data2   
0   A      0      5         
1   B      1      0    
2   C      2      3     
3   A      3      3
4   B      4      7
5   C      5      9
Mittels der Funktion

Code: Alles auswählen

 df.groupby('key').transform(lambda x: x - x.mean())
zentriere ich die Werte der "data1" und "data2". Nun habe ich in einigen Lehrbüchern gelesen, dass man anstatt der lambda Funktion eher die List comprehension verwenden soll.
Meine Frage wäre nun wie diesen Ausruck durch eine LC ersetzen kann....
Es ist ja so, dass, "groupby" ein groupby Objekt zurück gibt auf welches zugegriffen und welches weiter verwendet werden kann.
Meine Idee wäre nun etwas wie:

Code: Alles auswählen

df.groupby("key").transform([x-x.mean() for x in df.groupby("key")])
Das Problem scheint hierbei zu sein, dass die LC nicht "weiss" welches Element des von df.groupby("key") zurückgegebenen Objektes sie als x nehmen soll da ich immer die Fehlermeldung bekomme:

AttributeError: 'tuple' object has no attribute 'mean'

Ich hoffe mir kann jemand weiterhelfen.

Lg

Re: lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 09:47
von nezzcarth
So allgemein kann trifft diese Aussage meiner Meinung nach nicht zu, weil List-Comprehensions und Lambda-Ausdrücke für ganz verschiedene Dinge verwendet werden; LCs sind äquivalent zu Schleifen, die eine Liste befüllen, Lambda-Ausdrücke (anonyme Funktionen) sind äquivalent zu voll ausgeschrieben Funktionen.

Was ich mir vorstellen kann, ist, dass in den Lehrbüchern 'map' und/oder 'filter' gemeint waren. Dort verwendet man öfter mal Lambdas als Prädikat und diese würden sich in eine "Langform" aus List-Comprehension und Funktion umschreiben lassen.

Kurzum:Ich würde sagen, du kannst es so lassen, wie es ist.

Re: lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 09:57
von C#17
Hm okay nun ja also in dem Buch wird es tatsächlich so beschrieben dass man mit den List-Comprehensions alles erreichen kann was man auch mit lambda erreichen kann...

Wie könnte ich das Problem aber dennoch mit einer LC lösen?

Re: lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 10:29
von Hyperion
C#17 hat geschrieben:Hm okay nun ja also in dem Buch wird es tatsächlich so beschrieben dass man mit den List-Comprehensions alles erreichen kann was man auch mit lambda erreichen kann...
Dann ist das aber kein so dolles Buch...
Wie könnte ich das Problem aber dennoch mit einer LC lösen?
Wieso willst Du das denn unbedingt? Das sieht doch ganz gut und lesbar aus!

Re: lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 10:41
von C#17
Weil ich lernen will und verstehen möchte :)

Re: lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 10:41
von nezzcarth
C#17 hat geschrieben:Hm okay nun ja also in dem Buch wird es tatsächlich so beschrieben dass man mit den List-Comprehensions alles erreichen kann was man auch mit lambda erreichen kann...
Ich würde Hyperion zustimmen.

Ich weiß ja nicht, ob ich was übersehe, aber:
Wenn du wirklich daran festhalten möchtest, musst du denke ich 'transform' loswerden und das durch etwas Eigenes ersetzen. 'Transform' ist eine Funktion(/Methode) höherer Ordnung (wie auch map oder filter) und braucht als solche eine Funktion (bzw. ein callable) als erstes Argument. Dass du überhaupt eine Liste übergeben kannst, liegt daran, dass 'transform' auch Listen und Dictionaries von Funktionen oder Strings mit Funktionennamen nimmt. Diese werden auf die Elemente des Dataframes angewendet und es wird ein neues Dataframe mit den Resultaten, die der Funktionsaufruf für jedes Element ergeben hat, erzeugt und zurückgegeben. Diesen Ablauf müsstest du dann halt selbst in eine LC gießen.

Re: lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 11:44
von C#17
okay vielen Dank. Das mit der Funktion welche an transform() übergeben werden muss hat mir i wie gefehlt... d.h.

Code: Alles auswählen

df.groupby('key').transform(lambda x: x - x.mean())
ist so zu sagen die Kurzfassung von:

Code: Alles auswählen

def normalize(x):
    x= x-x.mean()
    return(x)

print(df.groupby("key").transform(normalize))
und damit macht es eigentlich keinen Sinn es mit einer LC zu machen, da dies nur "umständlich" (vor allem für einen Neuling) zu bewerkstelligen ist....
Vielen Dank!

Re: lambda durch List comprehension ersetzen

Verfasst: Montag 5. Juni 2017, 14:10
von nezzcarth
Ja, im Prinzip schon, die Funktion ist nur ein Ersatz für den Lambda-Ausdruck, nicht den gesamten Aufruf von 'transform'. Üblicherweise würde man die Funktion noch etwas vereinfachen, in dem man die Klammern bei 'return' weglässt und das Ergebnis gleich zurück gibt, statt es erst an einen Namen zu binden:

Code: Alles auswählen

def normalize(x):
    return x - x.mean()
Allerdings ist es wie gesagt empfehlenswert, es so zu lassen, wie du es hattest.