大熊猫的分组比和计算比率

时间:2020-02-07 17:39:36

标签: python pandas

我有以下代码按年龄计算转化率(转化列具有两个值1,分别代表转化成功和0失败)。但是我想知道是否还有一种更“优雅”的方式来做到这一点?

import pandas as pd
import numpy as np

np.random.seed(30)

### MAKE PSEUDODATA
start_date,end_date = '1/1/2015','12/31/2018'
date_rng = pd.date_range(start= start_date, end=end_date, freq='D')
length_of_field = date_rng.shape[0]
df = pd.DataFrame(date_rng, columns=['date'])
df['age'] = np.random.randint(18,100,size=(len(date_rng)))
df['conversion'] = np.random.randint(0,2,size=(len(date_rng)))

### ACTUAL CONVERSION CALCULATION 
conversion_by_age = df.groupby(by='age')['conversion'].agg(['count','sum'])
conversion_by_age['rate'] = df.groupby(by='age')['conversion'].sum()/df.groupby(by='age')['conversion'].count()
print(conversion_by_age)

2 个答案:

答案 0 :(得分:4)

一旦定义了groupby,就无需再执行多次。对于系列/ df除法,我将使用div而不是运算符/。我将更改最后两行并获得相同的结果:

conversion_by_age['rate'] = conversion_by_age['sum'].div(conversion_by_age['count'])
print(conversion_by_age)

另一种方法,只用一行代码,就可以使用rategroupby内计算lambda列:

conversion_by_age = df.groupby(by='age').apply(lambda x: x['conversion'].sum() / x['conversion'].count())

时间比较:

最后,即使lambda是一个衬纸,它也比使用.div()慢得多。这些是运行1000次的时间:

  1. 方法1时间:0.00981671929359436s +/- 0.0007387502003829031
  2. 方法2时间:0.015887546062469483 +/- 0.0014185150269994534

答案 1 :(得分:0)

“命名聚合”词典在大熊猫中current best-practice(需要熊猫。版本> 0.25.0)。

但是,您仍然需要在第二行中计算'rate',因为任何单线都将使用非矢量化的熊猫操作,并且速度要慢得多。总体而言,我建议:

conversion_by_age = df.groupby(by='age').agg(**{'conversion_count':('conversion','count'), 'conversion_sum':('conversion','sum')})
conversion_by_age['rate'] = conversion_by_age['conversion_sum'].div(conversion_by_age['conversion_count'])