UDF函数:客户连续三天经营判断方法的趣味实现。
最近有同事问了我一个关于数据处理的面试题,“如何在一张业务数据表中判断客户是否连续经营了三天”。当时给出的答案是如果是增量计算的话,只要每天把前三天的数据找出来,按客户,按日期GROUP BY一下,然后再看看COUNT是否等于3就行了。如果要考虑处理历史数据的话,就可能需要建一个每天对应前三天的临时表,再用业务表去关联,形成笛卡尔再去判断。
刚好最近在学习使用python写udf,于是又把这个问题挖出来研究了一下。
具体的实现思路是:
1、确保业务表按客户,日期的排序(并且已做过group by)
2、python函数里判断
1)、本条数据是否于上条数据的客户一致,
2)、本条数据的日期与上条数据日期是否相差一天
3)、本条数据的日期与上两条数据日期是否相差两天
判断条件都成立则为Y,判断条件不成立则为N
--------------------------------------------------------------------------------------------------------------------------
我们先看具体结果:
1、创建临时表放置虚构的数据。
2、按顺序匹配可以看到得出的结果是正确的。(第3条数据和第9条数据都标记为Y)
-------------------------------------------------------------------------------------------------------------------------
具体代码实现看下面:
#!/home/tops/bin/python
import calendar
import math
import sys
import datetime
def main():
try:
#testword=['a,2017-09-01','a,2017-09-02','a,2017-09-03','a,2017-09-04','a,2017-09-05','a,2017-09-06','a,2017-09-07','a,2017-09-11','a,2017-09-12','a,2017-09-28','a,2017-09-29','a,2017-09-30','a,2017-10-01','a,2017-10-02','b,2017-09-01','b,2017-09-02','b,2017-09-03','b,2017-09-04','b,2017-09-05','b,2017-09-06',]
str2=''
str3=''
datetime2=datetime.datetime.strptime('0001-01-01','%Y-%m-%d')
datetime3=datetime.datetime.strptime('0001-01-01','%Y-%m-%d')
for line in sys.stdin:
p = line.strip().split('\t')
#print p
datetime1 = datetime.datetime.strptime(p[1],'%Y-%m-%d')
str1=p[0]
if str1==str2:
#print 'the same of two cus'
if str(datetime1-datetime2)=='1 day, 0:00:00':
#print 'juge the business apart one day'
if str(datetime1-datetime3)=='2 days, 0:00:00':
#print 'juge the business apart two day'
print 'Y'
else:
print 'N'
else:
print 'N'
else:
print 'N'
#else: print 'not the same cus'
#print '----------------------------------------------------------'
str3=str2
datetime3=datetime2
str2=str1
datetime2=datetime1
except:
return None
if __name__ == "__main__":
main()
逻辑比较简单,如果要判断多天建议多写个循环判断。
最后把文件布上服务器,在hive或者spartk上执行即可。