2013-10-27 417 views
11

我知道傳遞一個函數作爲一個組鍵可以爲每個索引值調用一次函數,返回值被用作組名。我無法弄清楚的是如何調用列值的函數。Groupby with User Defined Functions Pandas

因此,我可以做到這一點:

people = DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis']) 
def GroupFunc(x): 
    if len(x) > 3: 
     return 'Group1' 
    else: 
     return 'Group2' 

people.groupby(GroupFunc).sum() 

這將數據分成兩組,其中一個具有長度3或更小的索引值,和其他與長度三個或更多個。但是,我怎樣才能傳遞一個列值?因此,例如,如果對於每個指數點列d值大於1,我知道我可以做到以下幾點:

people.groupby(people.a > 1).sum() 

但我想知道如何以供將來參考用戶定義的函數做到這一點。

喜歡的東西:

def GroupColFunc(x): 
if x > 1: 
    return 'Group1' 
else: 
    return 'Group2' 

但我怎麼稱呼呢? 我試過

people.groupby(GroupColFunc(people.a)) 

和類似的變體,但這是行不通的。

如何將列值傳遞給函數? 我將如何傳遞多個列值以people.a> people.b爲例進行分組?

回答

19

要按> 1組,您可以定義您的函數:

>>> def GroupColFunc(df, ind, col): 
...  if df[col].loc[ind] > 1: 
...   return 'Group1' 
...  else: 
...   return 'Group2' 
... 

的然後調用它像

>>> people.groupby(lambda x: GroupColFunc(people, x, 'a')).sum() 
       a   b   c   d  e 
Group2 -2.384614 -0.762208 3.359299 -1.574938 -2.65963 

或者你可以只用匿名函數做到這一點:

>>> people.groupby(lambda x: 'Group1' if people['b'].loc[x] > people['a'].loc[x] else 'Group2').sum() 
       a   b   c   d   e 
Group1 -3.280319 -0.007196 1.525356 0.324154 -1.002439 
Group2 0.895705 -0.755012 1.833943 -1.899092 -1.657191 

正如在documentation中所說的,你也可以通過傳遞組提供一個標籤 - >組名ma pping:

>>> mapping = np.where(people['b'] > people['a'], 'Group1', 'Group2') 
>>> mapping 
Joe  Group2 
Steve  Group1 
Wes  Group2 
Jim  Group1 
Travis Group1 
dtype: string48 
>>> people.groupby(mapping).sum() 
       a   b   c   d   e 
Group1 -3.280319 -0.007196 1.525356 0.324154 -1.002439 
Group2 0.895705 -0.755012 1.833943 -1.899092 -1.657191 
+0

感謝您的徹底解答。我正在與麥金尼的熊貓書一起工作,它非常接近真正的徹底,但像這樣的解釋我覺得很難追查。謝謝 –