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
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.
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!
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]
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