广告效果分析-广告点击率mysql+pandas
本题知识点:case when ;fillna;apply……
链接
目录
思路:
Mysql
pandas
思路:
(以下 clicked,viewed,ignored 简称为 c,v,g)
看公式,对于没有全是ignore记录的广告也需要有ctr结果(0),
所以我们要保留所有的广告记录。而不是一开始就把所有ignore记录筛掉去计算。
这里有两种方法:
方法1(鸡肋版):
分别按照ad_id 分组后筛出 action= v或c的记录然后计数,然后两个分组结果合并后对两个计数列相加得到v+c列,最后c列 / v+c列 得到 ctr。
但是这种方法鸡肋就鸡肋在现在得到ctr的结果中并没有包含action全是g的广告。因为前面分组计数时根据action = c或 v筛选后g记录就不在结果中了。
此时你就得回到ads表中找到去重后的ad_id,再与ctr结果左连表后 以0填充空值。 略显麻烦
所以
方法2 :
ads表中先新添加一列tag,action = c 或 v 时 tag = 1, action = g 时 tag = 0。
然后根据 ad_id 分组后对tag 求和 得到结果表 tvc,得到的sum就是 v+c,且 action 全是 g的广告也被保留在这个结果中,sum结果为0。
然后再单独根据 action = c 从表中筛记录 ,按ad_id 分组后进行计数得到c,结果表命名tc。
tvc 左连表 tc ,在结果表中 c列 / v+c 列 得到 ctr ,其中 v+c = 0也参与计算但是不会有结果,会置空,最后替换空值为0。
方法2比方法1就显得不那么绕了。
Mysql
with tvc as
(select ad_id,sum(tag) as vc from
(
select ad_id,
case when action = 'Clicked' or action = 'Viewed' then 1
else 0 end as tag
from ads
) t group by ad_id)
,tc as
(
select ad_id,count(1) as c from
ads where action = 'Clicked'
group by ad_id)select tvc.ad_id, ifnull(round(c/vc,4)*100,0) as ctr
from tvc left join tc on tvc.ad_id = tc.ad_id
order by ctr desc, ad_id asc
pandas
import pandas as pd
def ads_performance(ads: pd.DataFrame) -> pd.DataFrame:ads['tag'] = ads.apply(lambda row:1 if row['action'] == 'Clicked' or row['action'] == 'Viewed' else 0,axis=1)df1 = ads.groupby(by='ad_id')['tag'].sum().reset_index(name='v+c')df2 = ads[ads['action'] == 'Clicked'].groupby(by='ad_id')['action'].count().reset_index(name='c')df = pd.merge(left=df1,right=df2,how='left',on='ad_id').fillna(0)df['ctr'] = round(df['c'] / df['v+c'],4) * 100return df[['ad_id','ctr']].fillna(0).sort_values(by=['ctr','ad_id'],ascending=[False,True])