2014-01-27 9 views
21

Meine erste SO Frage: Ich bin verwirrt über dieses Verhalten der Methode apply von groupby in Pandas (0.12.0-4) scheint es, um die Funktion ZWEIMAL auf die erste Zeile anzuwenden eines Datenrahmens. Zum Beispiel:Python pandas groupby Objekt anwenden Methode Duplikate erste Gruppe

>>> from pandas import Series, DataFrame 
>>> import pandas as pd 
>>> df = pd.DataFrame({'class': ['A', 'B', 'C'], 'count':[1,0,2]}) 
>>> print(df) 
    class count 
0  A  1 
1  B  0  
2  C  2 

Ich prüfe zunächst, dass die groupby Funktion funktioniert ok, und es scheint in Ordnung zu sein:

>>> for group in df.groupby('class', group_keys = True): 
>>>  print(group) 
('A', class count 
0  A  1) 
('B', class count 
1  B  0) 
('C', class count 
2  C  2) 

Dann versuche ich, etwas zu tun ähnlich auf dem groupby-Objekt anwenden und ich die erste Zeile zweimal ausgeben:

>>> def checkit(group): 
>>>  print(group) 
>>> df.groupby('class', group_keys = True).apply(checkit) 
    class count 
0  A  1 
    class count 
0  A  1 
    class count 
1  B  0 
    class count 
2  C  2 

Jede Hilfe wäre willkommen! Vielen Dank.

Bearbeiten: @Jeff bietet die Antwort unten. Ich bin dicht und habe es nicht sofort verstanden, daher ist hier ein einfaches Beispiel, um zu zeigen, dass trotz des doppelten Ausdrucks der ersten Gruppe im obigen Beispiel die Methode apply nur einmal in der ersten Gruppe funktioniert und den ursprünglichen Datenrahmen nicht mutiert :

>>> def addone(group): 
>>>  group['count'] += 1 
>>>  return group 

>>> df.groupby('class', group_keys = True).apply(addone) 
>>> print(df) 

     class count 
0  A  1 
1  B  0 
2  C  2 

aber durch die Rückkehr des Verfahrens auf ein neues Objekt zuweisen, sehen wir, dass es wie erwartet funktioniert:

df2 = df.groupby ('Klasse', group_keys = Zutreffend) .anwenden (hinzufügen) drucken (df2)

 class count 
0  A  2 
1  B  1 
2  C  3 
+9

Dies überprüft, ob Sie die Daten in der Anwendung mutieren. Wenn Sie dann sind, muss es einen langsameren Weg als sonst nehmen. Es ändert die Ergebnisse nicht. – Jeff

+0

@Jeff: Könnte das Ergebnis des ersten Anrufs gespeichert werden, so dass es nicht erneut aufgerufen wird? Dies kann hilfreich sein, wenn die von apply aufgerufene Funktion lange dauert ... (zusammen mit intuitiver sein, da diese Frage viel aufkommt.) – unutbu

+0

@Jeff: Oder vielleicht könnte die Funktion in einem Memoizer verpackt sein ... – unutbu

Antwort

16

Das ist von Entwurf, wie here und here

beschrieben

Die apply Funktion der Form der zurückgegebenen Daten kennen muss, um auf intelligente Weise herauszufinden, wie es kombiniert wird. Dazu ruft er die Funktion (checkit in Ihrem Fall) zweimal auf, um dies zu erreichen.

Je nach tatsächlichem Anwendungsfall, können Sie den Anruf zu apply mit aggregate, transform oder filter ersetzen, wie here im Detail beschrieben. Diese Funktionen erfordern, dass der Rückgabewert eine bestimmte Form hat, und rufen Sie die Funktion daher nicht zweimal auf.

Allerdings - wenn die aufgerufene Funktion keine Nebenwirkungen hat, ist es höchstwahrscheinlich egal, dass die Funktion beim ersten Wert zweimal aufgerufen wird.