栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【学习记录】阿里天池SQL练习题05:用python和SQL方式

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【学习记录】阿里天池SQL练习题05:用python和SQL方式

学习处理1千万+数据集统计汇总及计算 数据来源:https://tianchi.aliyun.com/competition/entrance/231593/information 使用Coupon Usage Data for O2O中的数据集《ccf_online_stage1_train.csv》,试统计在2016年6月期间
1、线上总体优惠券弃用率为多少?
2、并找出优惠券弃用率最高的商家。
弃用率 = 被领券但未使用的优惠券张数 / 总的被领取优惠券张数

这题稍复杂,需要提前对【弃用率】做分析,所以先对数据源中的字段定义做分析,了解弃用率相关数据要如何获取?

数据详解
User_id:用户ID
Merchant_id:商户ID
Action:0 点击, 1购买,2领取优惠券
Coupon_id-优惠券ID:null表示无优惠券消费,此时Discount_rate和Date_received字段无意义
Discount_rate:优惠率:x in [0,1]代表折扣率;x:y表示满x减y。单位是元
Distance:user经常活动的地点离该merchant的最近门店距离是x*500米(如果是连锁店,则取最近的一家门店),xin[0,10];null表示无此信息,0表示低于500米,10表示大于5公里;
Date_received:领取优惠券日期
Date:消费日期:

        如果Date=null & Coupon_id != null,该记录表示领取优惠券但没有使用,即负样本;

        如果Date!=null & Coupon_id = null,则表示普通消费日期;

        如果Date!=null & Coupon_id != null,则表示用优惠券消费日期,即正样本

从数据源分析后了解到从【Date_received】字段中筛选出2016年6月期间数据,并从【Date】字段中筛选出符合领券要求的数据。

分析完毕后先做数据导入

import sqlalchemy as sac
import pandas as pd

engine=sac.create_engine('mysql+pymysql://user:password@host:3306/ali_sql')
df=pd.read_sql('select * from `ccf_online_stage1_train`',engine)

首先这里导入数据并没有做好,数据源此次有1千多万行,导入花费了很多时间。这里用了select * from 表的方式导入,其实可以先筛选下字段,不需要的字段去掉会比较合理。

df1=df[(df['Date']=='0000-00-00') & (df['Coupon_id']!='null')]
df1['Date_received']=pd.to_datetime(df1['Date_received']).dt.strftime('%Y-%m')
被领券但未使用数量=df1[df1['Date_received']=='2016-06']['Coupon_id'].count()

df2=df[df['Coupon_id']!='null']
df2['Date_received']=pd.to_datetime(df2['Date_received']).dt.strftime('%Y-%m')
总的被领取优惠券张数=df2[df2['Date_received']=='2016-06']['Coupon_id'].count()

print('弃用率: {:.2%}'.format(被领券但未使用数量/总的被领取优惠券张数))

接着开始梳理数据,先做条件筛选。

这次先筛选了【领券但未使用】,顺序上应该先处理时间数据。

但这里遇到个难题,如何处理'0000-00-00'的数据源?在SQL中其实代表的NaN值,但不理解为什么显示成这个样式。而导入到py中的数据都是object格式,如果用pd.to_datetime方法,无法转换这种样式的时间数据,导致无法筛选出2016年6月的数据。

所以就用笨办法,先筛选【Data】数据把‘0000-00-00’的值先过滤掉,过滤掉之后再处理时间数据类型。但这样做就比较麻烦,要多做一次筛选。如上代码,df1和df2都做了时间筛选处理。造成代码逻辑重复。

被领券但未使用的商家排名=df1[df1['Date_received']=='2016-06'].groupby('Merchant_id')[['Coupon_id']].count().sort_values(by='Coupon_id',ascending=False)
总的被领取优惠券数商家排名=df2[df2['Date_received']=='2016-06'].groupby('Merchant_id')[['Coupon_id']].count().sort_values(by='Coupon_id',ascending=False)
弃用率最高的商家=(被领券但未使用的商家排名/总的被领取优惠券数商家排名).sort_values(by='Coupon_id',ascending=False)[:1]

有了上面的数据预处理,商家的筛选结果就比较方便了。df.groupby方法把商家给筛选出来并计算排序

SQL代码
-- 线上总体优惠券弃用率为多少?

SELECt SUM(case when DATE='0000-00-00' AND Coupon_id IS NOT NULL then 1 ELSE 0 END)/
		SUM(case when Coupon_id IS NOT NULL then 1 ELSE 0 END) AS rate
FROM ccf_online_stage1_train
WHERe Date_received BETWEEN '2016-06-01' AND '2016-06-30'

-- 并找出优惠券弃用率最高的商家。
SELECt Merchant_id,(SUM(case when DATE='0000-00-00' AND Coupon_id IS NOT NULL then 1 ELSE 0 END)/SUM(case when Coupon_id IS NOT NULL then 1 ELSE 0 END)) AS rate
FROM ccf_online_stage1_train
WHERe Date_received BETWEEN '2016-06-01' AND '2016-06-30'
GROUP BY Merchant_id
ORDER BY rate DESC
LIMIT 1

 总结体会:

1、python在导入海量数据时,要先做筛选提高效率

2、python导入数据后要优先了解数据类型,便于数据预处理和清洗,为后面统计做准备

3、SQL在处理数据上要比python更加灵活,便捷。如果只是纯粹做数据处理应该用SQL,如果涉及后面的数据可视化,读写数据,预测等,那时才体现python优势。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/920938.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号