簡體   English   中英

Pandas GroupBy.apply 方法復制第一組

[英]Pandas GroupBy.apply method duplicates first group

我的第一個 SO 問題:我對 Pandas (0.12.0-4) 中 groupby 的 apply 方法的這種行為感到困惑,它似乎將函數 TWICE 應用於數據幀的第一行。 例如:

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

我首先檢查 groupby 函數是否正常工作,似乎沒問題:

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

然后我嘗試在 groupby 對象上使用 apply 做類似的事情,我得到了第一行輸出兩次:

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

任何幫助,將不勝感激! 謝謝。

編輯:@Jeff 在下面提供了答案。 一頭霧水,一時沒看懂,所以這里舉個簡單的例子來說明,盡管上面例子中第一組打印了兩次,但是apply方法對第一組只操作了一次,不會對原始數據框進行變異:

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

但是通過將方法的返回值分配給一個新對象,我們看到它按預期工作:

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

      class  count
0     A      2
1     B      1
2     C      3

這是設計使然,如此此處所述

apply函數需要知道返回數據的形狀才能智能地確定如何組合。 為此,它兩次調用該函數(在您的情況下為checkit )以實現此目的。

根據您的實際用例,您可以將apply調用替換為aggregatetransformfilter ,詳見此處 這些函數要求返回值是特定的形狀,因此不要兩次調用該函數。

但是 - 如果您正在調用的函數沒有副作用,則該函數在第一個值上被調用兩次很可能無關緊要。

這個“問題”現已得到修復:升級到 0.25+

從 v0.25 開始, GroupBy.apply()只會評估第一組一次。 GH24748

0.25.0 中的新功能(2019 年 7 月 18 日): Groupby.apply上的DataFrame僅評估第一組一次

文檔中的相關示例:

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                                                                                                                     

新行為 (>=v0.25):

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

   a  b
0  x  1
1  y  2

舊行為 (<=v0.24.x):

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

   a  b
0  x  1
1  y  2

Pandas 仍然使用第一組來確定apply是否可以走快速路徑。 但至少它不再需要對第一組進行兩次評估。 干得好,開發人員!

您可以使用 for 循環來避免 groupby.apply 重復的第一行,

日志樣本.csv

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

我的代碼片段

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)

輸出

[1]
[2, 2]
[3, 3, 3]
[4, 4, 4, 4]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM