it-swarm.com.de

Verwenden Sie Pandas groupby () + apply () mit Argumenten

Ich möchte df.groupby() zusammen mit apply() verwenden, um auf jede Zeile pro Gruppe eine Funktion anzuwenden.

Ich verwende normalerweise den folgenden Code, der normalerweise funktioniert (beachten Sie, dass dies ohne groupby() ist):

df.apply(myFunction, args=(arg1,))

Mit der groupby() habe ich folgendes versucht:

df.groupby('columnName').apply(myFunction, args=(arg1,))

Ich erhalte jedoch die folgende Fehlermeldung:

TypeError: myFunction () hat ein unerwartetes Schlüsselwortargument 'args' erhalten.

Daher ist meine Frage: Wie kann ich groupby() und apply() mit einer Funktion verwenden, die Argumente benötigt?

17
beta

pandas.core.groupby.GroupBy.apply hat NICHT named Parameter args, aber pandas.DataFrame.apply hat es.

Also probiere es aus:

df.groupby('columnName').apply(lambda x: myFunction(x, arg1))

oder wie von @Zero vorgeschlagen:

df.groupby('columnName').apply(myFunction, ('arg1'))

Demo:

In [82]: df = pd.DataFrame(np.random.randint(5,size=(5,3)), columns=list('abc'))

In [83]: df
Out[83]:
   a  b  c
0  0  3  1
1  0  3  4
2  3  0  4
3  4  2  3
4  3  4  1

In [84]: def f(ser, n):
    ...:     return ser.max() * n
    ...:

In [85]: df.apply(f, args=(10,))
Out[85]:
a    40
b    40
c    40
dtype: int64

bei Verwendung von GroupBy.apply können Sie entweder benannte Argumente übergeben:

In [86]: df.groupby('a').apply(f, n=10)
Out[86]:
    a   b   c
a
0   0  30  40
3  30  40  40
4  40  20  30

ein Tupel von Argumenten:

In [87]: df.groupby('a').apply(f, (10))
Out[87]:
    a   b   c
a
0   0  30  40
3  30  40  40
4  40  20  30
13
MaxU

Einige Verwirrung darüber, warum die Verwendung eines args-Parameters einen Fehler auslöst, könnte darauf zurückzuführen sein, dass pandas.DataFrame.apply einen args-Parameter (ein Tuple) hat, während pandas.core.groupby.GroupBy.apply dies nicht tut.

Wenn Sie also .apply für einen DataFrame selbst aufrufen, können Sie dieses Argument verwenden. Wenn Sie .apply für ein Groupby-Objekt aufrufen, ist dies nicht möglich.

In der Antwort von @ MaxU wird der Ausdruck lambda x: myFunction(x, arg1) an func (den ersten Parameter) übergeben. Es ist nicht erforderlich, zusätzlichen *args/**kwargs anzugeben, da arg1 in Lambda angegeben ist.

Ein Beispiel:

import numpy as np
import pandas as pd

# Called on DataFrame - `args` is a 1-Tuple
# `0` / `1` are just the axis arguments to np.sum
df.apply(np.sum, axis=0)  # equiv to df.sum(0)
df.apply(np.sum, axis=1)  # equiv to df.sum(1)


# Called on groupby object of the DataFrame - will throw TypeError
print(df.groupby('col1').apply(np.sum, args=(0,)))
# TypeError: sum() got an unexpected keyword argument 'args'
5
Brad Solomon

Für mich

df2 = df.groupby('columnName').apply(lambda x: my_function(x, arg1, arg2,))

hat funktioniert

3
Hitesh Somani