我有以下代码按年龄计算转化率(转化列具有两个值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)
答案 0 :(得分:4)
一旦定义了groupby
,就无需再执行多次。对于系列/ df除法,我将使用div
而不是运算符/
。我将更改最后两行并获得相同的结果:
conversion_by_age['rate'] = conversion_by_age['sum'].div(conversion_by_age['count'])
print(conversion_by_age)
另一种方法,只用一行代码,就可以使用rate
在groupby
内计算lambda
列:
conversion_by_age = df.groupby(by='age').apply(lambda x: x['conversion'].sum() / x['conversion'].count())
最后,即使lambda
是一个衬纸,它也比使用.div()
慢得多。这些是运行1000次的时间:
答案 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'])