计算MAD(平均绝对偏差)GroupBy Pandas

Hyp*_*nja 6 python group-by aggregate dataframe pandas

我有一个数据帧:

Type Name Cost
  A   X    545
  B   Y    789
  C   Z    477
  D   X    640
  C   X    435
  B   Z    335
  A   X    850
  B   Y    152
Run Code Online (Sandbox Code Playgroud)

我的数据框中有所有这样的组合,类型为['A','B','C','D']和名称['X','Y','Z'].我使用groupby方法获取特定组合的统计数据,如AX,AY,AZ.这是一些代码:

df = pd.DataFrame({'Type':['A','B','C','D','C','B','A','B'] ,'Name':['X','Y','Z','X','X','Z','X','Y'], 'Cost':[545,789,477,640,435,335,850,152]})
df.groupby(['Name','Type']).agg([mean,std])  
#need to use mad instead of std  
Run Code Online (Sandbox Code Playgroud)

我需要消除超过3 MAD的观察结果; 就像是:

test = df[np.abs(df.Cost-df.Cost.mean())<=(3*df.Cost.mad())]
Run Code Online (Sandbox Code Playgroud)

我对此感到困惑,因为df.Cost.mad()返回整个数据上的Cost的MAD而不是特定的Type-Name类别.我怎么能把两者结合起来?

Jul*_*nck 4

您可以使用groupbytransform创建可用于过滤数据的新数据系列。

groups = df.groupby(['Name','Type'])
mad = groups['Cost'].transform(lambda x: x.mad())
dif = groups['Cost'].transform(lambda x: np.abs(x - x.mean()))
df2 = df[dif <= 3*mad]
Run Code Online (Sandbox Code Playgroud)

然而,在这种情况下,没有行被过滤掉,因为差值等于平均绝对偏差(组最多只有两行)。