Pandy GroupBy.zastosuj metodę duplikuje pierwszą grupę

Moje pierwsze pytanie: Jestem zdezorientowany co do tego zachowania metody apply of groupby w Pandzie (0.12.0-4), wydaje się, że funkcja jest stosowana dwa razy do pierwszego wiersza ramki danych. Na przykład:

>>> 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

Najpierw sprawdzam, czy funkcja groupby Działa ok i wydaje się być w porządku:

>>> 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)

Potem próbuję zrobić coś podobnego używając apply na obiekcie groupby i otrzymuję wyjście pierwszego wiersza dwa razy:

>>> 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
Każda pomoc będzie mile widziana! Dzięki.

Edit: @ Jeff podaje odpowiedź poniżej. Jestem gęsty i nie zrozumiałem tego od razu, więc oto prosty przykład, aby pokazać, że pomimo podwójnego wydruku pierwszej grupy w powyższym przykładzie, metoda apply działa tylko raz na pierwszej grupie i nie mutuje oryginalnej ramki danych: {]}

>>> 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

Ale przypisując zwracanie metody do nowego obiektu, widzimy, że działa ona zgodnie z oczekiwaniami:

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

      class  count
0     A      2
1     B      1
2     C      3
Author: Ch3steR, 2014-01-27

3 answers

Jest to projekt, zgodnie z opisem tutaj i tutaj

Funkcja apply musi znać kształt zwracanych danych, aby inteligentnie dowiedzieć się, w jaki sposób zostaną one połączone. Aby to zrobić, dwukrotnie wywołuje funkcję (checkit w Twoim przypadku), aby to osiągnąć.

W zależności od rzeczywistego przypadku użycia, możesz zamienić wywołanie na apply na aggregate, transform lub filter, jak opisano szczegółowo tutaj . Funkcje te wymagają, aby wartość zwracana była określonym kształtem, a więc nie wywołaj funkcji dwa razy.

Jednakże-jeśli wywołana funkcja nie ma skutków ubocznych, najprawdopodobniej nie ma znaczenia, że funkcja jest wywoływana dwa razy na pierwszej wartości.

 39
Author: Zero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 01:39:33

Ten "problem" został naprawiony: Upgrade do 0.25 +

Począwszy od wersji 0.25, GroupBy.apply() oceni pierwszą grupę tylko raz. Zobacz GH24748 .

Co nowego w 0.25.0 (lipiec 18, 2019): Groupby.apply on DataFrame ocenia pierwszą grupę tylko raz

Odpowiedni przykład z dokumentacji:

pd.__version__                                                                                                          
# '0.25.0.dev0+590.g44d5498d8'

df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})                                                                      

def func(group): 
    print(group.name) 
    return group                                                                                                                     

Nowe zachowanie (>=v0. 25):

df.groupby('a').apply(func)                                                                                            
x
y

   a  b
0  x  1
1  y  2

Stare zachowanie (

df.groupby('a').apply(func)
x
x
y

   a  b
0  x  1
1  y  2

Pandy nadal używa pierwszej grupy, aby określić, czy apply może pościć ścieżka czy nie. Ale przynajmniej nie musi już dwukrotnie Oceniać pierwszej grupy. Dobra robota, devs!

 11
Author: cs95,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-30 06:43:47

Możesz użyć pętli for, aby uniknąć groupby.zastosuj duplikat pierwszego wiersza,

Log_sample.csv

guestid,keyword
1,null
2,null
2,null
3,null
3,null
3,null
4,null
4,null
4,null
4,null

Mój kod snippit

df=pd.read_csv("log_sample.csv") 
grouped = df.groupby("guestid")

for guestid, df_group in grouped:
    print(list(df_group['guestid'])) 

df.head(100)

Wyjście

[1]
[2, 2]
[3, 3, 3]
[4, 4, 4, 4]
 2
Author: geosmart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 03:17:33