2017-04-18 118 views
8

我想使用df.groupby()結合apply()將函數應用於每個組的每行。使用熊貓groupby()+ apply()與參數

我通常使用下面的代碼,它通常工作(注意,這是不groupby()):

df.apply(myFunction, args=(arg1,)) 

隨着groupby()我試過如下:

df.groupby('columnName').apply(myFunction, args=(arg1,)) 

不過,我得到出現以下錯誤:

TypeError: myFunction() got an unexpected keyword argument 'args'

因此,我的問題是:如何將groupby()apply()用於需要參數的函數?

+2

這與'df.groupby( '列名')工作申請(myFunction的,( 'ARG1'))' – Zero

+0

@Zero這是偉大的答案,因爲它是非常相似OP的嘗試解決方案,並不需要lambda。我建議你將它發佈爲答案。 – DontDivideByZero

+0

@零,我有和OP一樣的情節,但這對我不起作用 - 我仍然得到和OP一樣的錯誤。另外,請問爲什麼你的評論應該起作用,爲什麼OP的方法(與我的方法相同)不適用?我沒有發現它記錄在任何地方 –

回答

8

pandas.core.groupby.GroupBy.apply沒有命名參數args,但pandas.DataFrame.apply確實有它。

那麼試試這個:

df.groupby('columnName').apply(lambda x: myFunction(x, arg1)) 

@Zero的建議:

df.groupby('columnName').apply(myFunction, ('arg1')) 

演示:

In [82]: df = pd.DataFrame(np.random.randint(5,size=(5,3)), columns=list('abc')) 

In [83]: df 
Out[83]: 
    a b c 
0 0 3 1 
1 0 3 4 
2 3 0 4 
3 4 2 3 
4 3 4 1 

In [84]: def f(ser, n): 
    ...:  return ser.max() * n 
    ...: 

In [85]: df.apply(f, args=(10,)) 
Out[85]: 
a 40 
b 40 
c 40 
dtype: int64 
使用 GroupBy.apply時,你可以通過其中一個命名參數

In [86]: df.groupby('a').apply(f, n=10) 
Out[86]: 
    a b c 
a 
0 0 30 40 
3 30 40 40 
4 40 20 30 

的參數的元組:

In [87]: df.groupby('a').apply(f, (10)) 
Out[87]: 
    a b c 
a 
0 0 30 40 
3 30 40 40 
4 40 20 30 
+0

就像一個魅力。謝謝。 – beta

+1

你確定沒有辦法在元組中傳遞'args'參數嗎?我已經看到在其他地方的'.apply'上使用它,並且它不需要lambda表達式 –

+1

@BradSolomon在問題的評論中看到了0的回答 – DontDivideByZero

2

有些困惑在這裏了,爲什麼使用args參數拋出一個錯誤可能來自一個事實,即pandas.DataFrame.apply確實有一個args參數(一個元組)幹,而pandas.core.groupby.GroupBy.apply不。

因此,當您在DataFrame本身上調用.apply時,可以使用此參數;當你在groupby對象上調用.apply時,你不能。

在@ MaxU的回答中,表達式lambda x: myFunction(x, arg1)傳遞給func(第一個參數);沒有必要指定額外的*args/**kwargs,因爲在lambda中指定了arg1

一個例子:

import numpy as np 
import pandas as pd 

# Called on DataFrame - `args` is a 1-tuple 
# `0`/`1` are just the axis arguments to np.sum 
df.apply(np.sum, axis=0) # equiv to df.sum(0) 
df.apply(np.sum, axis=1) # equiv to df.sum(1) 


# Called on groupby object of the DataFrame - will throw TypeError 
print(df.groupby('col1').apply(np.sum, args=(0,))) 
# TypeError: sum() got an unexpected keyword argument 'args'