产品经理数据分析不求人(3) - 拼团购数据清洗

产品经理数据分析不求人(1) - 第一个Python程序

产品经理数据分析不求人(2) - Pandas处理Excel

有了前两篇的基础,现在可以来看看如何通过简单的代码结合工作中的实际场景进行简单的分析,目标对象是团购数据。原本我想直连Hive取数,但是因为安全限制原因只能通过工具导出Excel再做进一步的分析。首先要考虑清楚通过数据分析希望得到什么结论,需要哪些字段作为输入条件,需要哪些字段验证猜想。拼团是一个社会化传播的行为,电商公司对商品进行让利补贴,并提供全场免邮,希望能带动新客实现首单的购买,所以这里有三个关键元素: 新客,商品,成本,成功的拼团活动应该是传播力强,新客占比高,拉新成本有效控制。

先从商品角度来看,根据不同的品类,品牌,价格,毛利等因素制定补贴规则,如9.9元抢购甚至1元拼团栏目之类商品补贴成本比较高,自然也希望能带来更多的新客。一方面我们可以考虑提升成团门槛,仅限新客成团,并增加成团人数,另一方面也可以考虑把珍稀资源分配给最有价值的用户,也就是拉新能力最强的用户。那么从用户角度来分析,什么样的用户拉新能力最强呢? 动动脚指头也能想到社交价值衰减规律会对拉新价值带来影响,如果一个用户多次参加拼团,反复刷洗自己的朋友圈,那么他能带来新客的概率就会很低了。除此之外还有哪些因素可能会影响到拼团的效果呢? 我们可以通过数据分析快速验证一下。

我需要的数据分为input(因子)和output(结果)两部分,因子可以有很多,但是真正有影响力的关键因子被埋藏在大量无效因子里面,我们必须把这些关键因子挖掘出来,有的因果关系并不是显而易见的,必须通过数据挖掘才能发现其中奥秘,比如用户手机剩余电量对转化率有戏剧性影响。再就是我所分析场景的核心KPI指标。对于拼团这个案例而言,用户相关因子可以有机型,注册时间,会员等级,性别,婚姻状态,地理位置,年龄,消费水平等等,可以有几百个变量,对于示例来说我们取十几个变量就够了。对于KPI指标,我会关注成团数和最关键的拉新人数。

以下是我选出来可用的字段,group_count和new_user_count分别是成团数和拉新人数,birthday和reg_time我用来衍生转化为其他字段,其余的都是可以直接使用的因子。

我拿到了十几万数据来做聚类分析,统计前要对原始数据加工清洗一下,首先我发现星座这个字段的值是错的,居然有70多个不同的值。这没关系,可以直接从生日中的月和日来推算,先写一个转化函数。稍微简单说明一下, u前缀表示字符是一个unicode对象,否则中文会乱码。lambda是匿名函数的写法,输入是日期,如果这个日期大于month, day则返回True, 否则返回False. filter对range序列中的元素依次执行前面的匿名函数,将执行结果为True的元素组成一个List返回。如果有兴趣可以google一下具体了解细节,不想了解也没关系,把下面的函数拷贝到代码中直接使用即可。

Tips: 我们开始用到了函数定义,首行结尾必须有个冒号,函数体必须保持一个同样的缩进(tab), 否则语法解析器会报错。

def derive_horoscope(month, day):
    value = (u'摩羯座',u'水瓶座',u'双鱼座',u'白羊座',u'金牛座',u'双子座',u'巨蟹座',u'狮子座',u'处女座',u'天秤座',u'天蝎座',u'射手座')
    range = ((1,20),(2,19),(3,21),(4,21),(5,21),(6,22),(7,23),(8,23),(9,23),(10,23),(11,23),(12,23))
    seq = list(filter(lambda date:date<=(month,day), range))
    return value[len(seq)%12]

既然修复了星座,也可以从生日中的年份计算出生肖, 这个函数更简单

def derive_zodiac(year):
    return u'猴鸡狗猪鼠牛虎兔龙蛇马羊' [year%12]

接下来我们要从生日得出年龄,为了方便做聚类统计,我希望把不同年龄映射到四组年龄段,需要先导入一个时间库datetime

import pandas as pd
import datetime
from dateutil.parser import parse

def derive_age_range(year):
    age = datetime.datetime.now().year - year   
    value = ('20-', '20s', '30s', '40+')
    range = (0, 20, 30, 40)
    seq = list(filter(lambda x:x<=age, range))
    return value[len(seq)-1]

最后我还要根据用户的注册时间推算出用户使用应用的年限,同样也映射到六个时间段

def derive_register_interval(year, month):
    year_diff = datetime.datetime.now().year - year
    month_diff = datetime.datetime.now().month - month
    interval = year_diff*12 + month_diff

    value = (u'三个月内', u'三到六个月', u'半年到一年', u'一年到两年', u'两年到三年', u'三年以上')
    range = (0, 3, 6, 12, 24, 36)
    seq = list(filter(lambda x:x<interval), range)
    return value[len(seq)-1]

现在我们终于可以put everything together, 调用上面的四个方法实现完整的数据转化逻辑了。

from dateutil.parser import parse

#检查日期是否合法
def is_date(string):
    try:       
        parse(string.strftime('%Y-%m-%d'))
        return True
    except Exception:
        return False

### 这里拷贝粘贴前面的四个函数进来 ###

#定义数据源和临时文件输出路径
input_file = "d:/dev/groupon_raw_data.xlsx"
output_file = "d:/dev/groupon_tmp.xlsx"

df = pd.read_excel(input_file)

#从生日和注册时间推算出新的所需字段
horoscope = []
zodiac = []
age_range = []
interval = []

for index, row in df.iterrows():
    bday = row['birthday']
    if (is_date(bday)):
        horoscope.append(derive_horoscope(bday.month, bday.day))
        zodiac.append(derive_zodiac(bday.year))
        age_range.append(derive_age_range(bday.year))
    else:
        horoscope.append("n/a")
        zodiac.append("n/a")
        age.append("n/a")

    reg_time = row['reg_time']    
    if (is_date(reg_time)):       
        interval.append(derive_register_interval(reg_time.year, reg_time.month))    
    else:     
        interval.append("n/a")

#丢弃掉错误的星座字段并新增推算出来的衍生字段
df.drop(['horoscope'], axis = 1, inplace = True)
df.insert(loc=4, column='horoscope', value=horoscope)
df.insert(loc=5, column='zodiac', value=zodiac)
df.insert(loc=6, column='age_range', value=age_range)
df.insert(loc=7, column='interval', value=interval)

#将转化后的数据写入临时文件
writer = pd.ExcelWriter(output_file)
df.to_excel(writer,'Sheet1',index=False)
writer.save()

print("Raw data processing completed!")

出于安全考虑原数据就不提供了,下一次我们将利用这个临时文件做简单的聚类分析,并以可视化方式呈现结论

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容