2017-10-18 159 views
1

我可以現在做熊貓以下,但我得到一個嚴峻的手指FutureWarning搖:Pandas Groupby:如何使用兩個lambda函數?

grpd = df.groupby("rank").agg({ 
    "mean": np.mean, "meian": np.median, "min": np.min, "max": np.max, 
    "25th percentile": lambda x: np.percentile(x, 25), 
    "75th percentile": lambda x: np.percentile(x, 75) 
}) 

下拋出一個錯誤,因爲我有兩個lambda函數:

percentile_25 = lambda x: np.percentile(x, 25) 
percentile_75 = lambda x: np.percentile(x, 75) 

df = diffs[["User Installs", "rank"]].dropna() 
grpd = df.groupby("shopping_rank").agg([ 
    np.mean, np.median, np.min, np.max, 
    percentile_25, percentile_75 
]) 

此拋出:

SpecificationError: Function names must be unique, found multiple named <lambda> 

我看起來能夠完成這項工作的唯一方法(不必忽視警告,我應該只是這樣做)是用精心製作的程序像下面

  1. SS定義我的DF與一個lambda函數(25個百分點),以及其他一切我需要(最小值,最大值等)
  2. 重命名的cols擺脫的多指標
  3. 與另一列我想(第75百分位)創建另一個DF,做另外一個分組,這個時候
  4. 重命名的cols再次(多指標感謝!)
  5. 加入回到原來的DF對指數

有什麼我在這裏失蹤?當然,有一種更好的方式可以做我認爲很常見的事情(使用兩個不能直接從numpy導入的聚合)。

+2

的可能的複製[在一個數據幀作出若干操作一次(https://stackoverflow.com/questions/46812223/make-several-operations-in-a-dataframe-at-once) – Wen

+0

函數是一個功能。 'lambda'表達式只是創建類型爲'function'的值的一種方法。 – chepner

+0

@chepner對不起,如果我不清楚。我不在乎函數是如何定義的,lambda表達式似乎存在於這個確切的用例中,所以我有點困惑,爲什麼它不起作用。 – BenDundee

回答

4

這是一個known bug,使用:

def percentile_25(x): return np.percentile(x, 25) 
def percentile_75(x): return np.percentile(x, 75) 
+0

這是一個很好的答案。我還建議用'functools.partial'將它們定義爲partials –

+0

我喜歡通過lambda命名函數,因爲合適的函數名稱*可以避免在數據幀上調用'.rename()'(當傳遞多個函數時)。 –

1

試試下面的小黑客:

percentile_25 = lambda x: np.percentile(x, 25) 
percentile_25.__name__ = 'percentile_25' 
percentile_75 = lambda x: np.percentile(x, 75) 
percentile_75.__name__ = 'percentile_75' 
+0

只需使用'def percentile_25(x):return np.percentile(x,25)'。沒有理由在這裏使用'lambda'表達式。 – chepner

+1

@chepner,我用它,因爲OP問:'「如何使用兩個lambda函數?」 – MaxU

+0

我在想這樣的事情,我不知道如何構建函數 - 我一直使用lambda爲此的功能。 – BenDundee

0

這裏是另一個類似的方式來MaxU,但是,它允許你創建任意數量的lambda函數。所以,如果我們希望每個第10百分位可以做如下,

n_percentile_groups = 10 
lambda_list = [] 

for pcntl in np.linspace(10, 100, n_percentile_groups): 
    lmbd = lambda x, pcntl=pcntl: np.percentile(x, int(pcntl)) 
    lmbd.__name__ = 'percentile_%d' % pcntl 
    lambda_list.append(lmbd) 

現在通過lambda_listgroupby.agg()或與其他功能列表追加,e.g,lambda_list + [np.mean, np.min, ...]

如果您只想要5個不同的百分位數,那麼您可以更改n_percentile_groups = 5

最終,我不確定這是否是一種健全的或好的方法 - 可變數量的lambda表達式 - 但由於groupby deprecation - 0.21似乎是我知道的唯一方式。對此非常歡迎的評論。