Pandas groupby表示绝对偏差

时间:2013-12-05 01:17:23

标签: python-2.7 pandas

我有一个像这样的pandas数据框:

Product Group    Product ID    Units Sold    Revenue    Rev/Unit
A                451           8             $16        $2
A                987           15            $40        $2.67
A                311           2             $5         $2.50
B                642           6             $18        $3.00
B                251           4             $28        $7.00

我想把它变成这样:

Product Group    Units Sold    Revenue    Rev/Unit   Mean Abs Deviation
A                25            $61        $2.44      $0.24
B                10            $46        $4.60      $2.00

平均绝对偏差列将在第一个表中的Rev / Unit列上执行。棘手的是考虑到Rev / Unit计算背后的各自权重。

例如,采用产品组A的Rev / Unit的直接MAD将产生0.26美元。然而,在考虑到重量后,MAD将为0.24美元。

我知道使用groupby来获得销售单位和收入的简单总和,但我对如何对接下来的2列进行更复杂的计算感到有点迷失。

同时我们提供建议/帮助---是否有更简单的方法来创建/粘贴表格到SO帖子?

更新:

这样的解决方案会起作用吗?我知道它将用于求和字段,但不确定如何为后两个字段实现。

 grouped_df=df.groupby("Product Group")
 grouped_df.agg({
   'Units Sold':'sum',
   'Revenue':'sum',
   'Rev/Unit':'Revenue'/'Units Sold',
   'MAD':some_function})

2 个答案:

答案 0 :(得分:0)

你需要澄清“权重”是什么,我假设权重是销售单位的数量,但这会给你的结果带来不同的结果:

pv = df.pivot_table( rows='Product Group',
                     values=[ 'Units Sold', 'Revenue' ],
                     aggfunc=sum )
pv[ 'Rev/Unit' ] = pv.Revenue / pv[ 'Units Sold' ]

这给出了:

               Revenue  Units Sold  Rev/Unit
Product Group                               
A                   61          25      2.44
B                   46          10      4.60

至于WMAD:

def wmad( prod ):
    idx = df[ 'Product Group' ] == prod
    w = df[ 'Units Sold' ][ idx ]
    abs_dev = np.abs ( df[ 'Rev/Unit' ][ idx ] - pv[ 'Rev/Unit' ][ prod ] )
    return sum( abs_dev * w ) / sum( w )

pv[ 'Mean Abs Deviation' ] = [ wmad( idx ) for idx in pv.index ]

正如我所提到的那样给出了不同的结果

               Revenue  Units Sold  Rev/Unit  Mean Abs Deviation
Product Group                                                   
A                   61          25      2.44              0.2836
B                   46          10      4.60              1.9200

答案 1 :(得分:0)

根据建议的解决方案,您可以使用lambda函数对每一行进行操作,例如:

'Rev/Unit': lambda x: calculate_revenue_per_unit(x)

请记住x是每行的元组,因此您需要在calculate_revenue_per_unit函数中解压缩。