2014-01-27 35 views
21

我的第一個SO問題: 我對groupby的apply方法在pandas(0.12.0-4)中的這種行爲感到困惑,它似乎將函數TWICE應用到第一行的數據幀。例如:Python熊貓groupby對象apply方法複製第一組

>>> 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對象上做類似的事情,我也得到第一行輸出兩次:

>>> 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提供了下面的答案。我很密集,並且不能立即理解它,所以這裏有一個簡單的例子來說明,儘管在上面的例子中第一組的double打印輸出,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( '類',group_keys = True).apply(addone) print(df2)

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

這是檢查您是否正在變更申請中的數據。如果你是那麼它必須採取比其他方式更慢的路徑。它不會改變結果。 – Jeff

+0

@Jeff:可以保存第一次調用的結果,以免再次調用它?如果apply所調用的函數需要很長時間...(更直觀,因爲這個問題出現了很多),這可能會有所幫助。 – unutbu

+0

@Jeff:或者也許這個函數可能會被包裝在一個memoizer中... – unutbu

回答

16

這是由設計,如所描述herehere

apply功能需要知道返回的數據的形狀,以智能地找出如何將其組合。要做到這一點,它會調用函數(您的案例中的checkit)兩次以實現此目的。

根據您的實際使用情況,您可以用aggregatetransformfilter更換呼叫apply,在詳細描述here。這些函數要求返回值是一個特定的形狀,所以不要兩次調用該函數。

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