Spark销售数据统计
1、问题
数据:super_store.csv
1、求各个地区总的销售额和利润
2、求各个类别的销售数量和平均折扣
注:计算平均折扣时,不计算折扣为0的数据
3、求根据客户消费金额进行排序,列出排名前10的客户名称
4、求各个季度每个地区的总销售额,升序排列
5、求各个省/自治区的平均备货时间,降序排列
2、代码
(1)数据处理
# 引包
from pyspark import SparkContext
sc = SparkContext()
# 读文件 textFile
data = sc.textFile("/home/spark/Downloads/super_store.csv")
# 查看数据
# data.collect()
data.take(3)
# 过滤掉第一行表头
filter_data = data.filter(lambda x:'行 ID' not in x)
# 查看过滤掉表头的数据
filter_data.take(3)
# 对数据进行分词
split_data = filter_data.map(lambda x:x.split(","))
split_data.take(3)
# 过滤掉表头并进行分词
header = data.first()
split_data= data.filter(lambda line: line != header).map(lambda x:x.split(","))
split_data.take(3)
(2)求各个地区总的销售额和利润
# 求各个地区总的销售额和利润
# []中下标从0开始
# 提取出地区 销售额 利润的数据
q1_data = split_data.map(lambda x:(x[11],x[-4],x[-1]))
# q1_data.collect()
q1_data.take(3)
# 分别求各个地区总的销售额
# float转换字符串类型
split_data.map(lambda x:(x[11],float(x[-4]))).reduceByKey(lambda x,y:x+y).collect()
# 分别求各个地区总的利润
split_data.map(lambda x:(x[11],float(x[-1]))).reduceByKey(lambda x,y:x+y).collect()
# 一次性求各个地区总的销售额和利润
# (a,[x[0],x[1]])
# (b,[y[0],y[1]])
# lambda x,y:(x[0]+y[0],x[1]+y[1])
split_data.map(lambda x:(x[11],(float(x[-4]),float(x[-1])))).reduceByKey(lambda x,y:(x[0]+y[0],x[1]+y[1])).collect()
salesRDD = split_data.map(lambda x:(x[11],float(x[17])))
result_sales = salesRDD.reduceByKey(lambda x,y:x+y)
result_sales.collect()
profitRDD = split_data.map(lambda x:(x[11],float(x[20])))
result_profit = profitRDD.reduceByKey(lambda x,y:x+y)
result_profit.collect()
(3)求各个类别的销售数量和平均折扣
注:计算平均折扣时,不计算折扣为0的数据
# 求各个类别的销售数量和平均折扣
# 注计算平均折扣时,不计算折扣为0的数据
# 求各个类别的销售数量
split_data.map(lambda x:(x[13],float(x[-3]))).reduceByKey(lambda x,y:x+y).collect()
# 求各个类别平均折扣
# lambda x:x[-2]!='0'过滤掉折扣为0的数据
# lambda x:sum(list(x))/len(x)计算平均折扣
split_data.filter(lambda x:x[-2]!='0').map(lambda x:(x[13],float(x[-2]))).groupByKey().mapValues(lambda x:sum(list(x))/len(x)).collect()
(4)求根据客户消费金额进行排序,列出排名前10的客户名称
# 求根据客户消费金额进行排序,列出排名前10的客户名称
# ascending=False降序排列
split_data.map(lambda x:(x[6],float(x[-4]))).reduceByKey(lambda x,y:x+y).sortBy(lambda x:x[1],ascending=False).take(10)
(5)求各个季度每个地区的总销售额,升序排列
# 求各个季度每个地区的总销售额,升序排列
# sortBy默认升序排列
# datetime.strptime(x[2],'%Y/%m/%d').month:使用"%Y/%m/%d"格式解析为日期时间对象,并提取出月份
# (datetime.strptime(x[2],'%Y/%m/%d').month-1)//3+1:通过计算月份来确定季度。首先,将月份减1,得到的结果再除以3取整数商,最后加1,即可得到季度。因为每个季度包含3个月,所以对月份减1再除以3可以将1-3月划分为第1季度,4-6月划分为第2季度,以此类推。
from datetime import datetime
split_data.map(lambda x:(((datetime.strptime(x[2],'%Y/%m/%d').month-1)//3+1,x[11]),float(x[-4]))).reduceByKey(lambda x,y:x+y).sortBy(lambda x:x[1]).collect()
(6)求各个省/自治区的平均备货时间,降序排列
# 求各个省/自治区的平均备货时间,降序排列
# 备货时间=发货日期-订单日期
# (datetime.strptime(x[3],'%Y/%m/%d')-datetime.strptime(x[2],'%Y/%m/%d')).days):使用"%Y/%m/%d"格式解析为日期时间对象,计算备货时间,并提取出天数
# .days()获取其天数
# ascending=False降序排列
from datetime import datetime
split_data.map(lambda x:(x[9],(datetime.strptime(x[3],'%Y/%m/%d')-datetime.strptime(x[2],'%Y/%m/%d')).days))\
.groupByKey().mapValues(lambda x:sum(list(x))/len(x))\
.sortBy(lambda x:x[1],ascending=False).collect()
3、完整代码
# 引包
from pyspark import SparkContext
sc = SparkContext()
# 读文件 textFile
data = sc.textFile("/home/spark/Downloads/super_store.csv")
# 查看数据
# data.collect()
data.take(3)
# 过滤掉第一行表头
filter_data = data.filter(lambda x:'行 ID' not in x)
# 查看过滤掉表头的数据
filter_data.take(3)
# 对数据进行分词
split_data = filter_data.map(lambda x:x.split(","))
split_data.take(3)
# 过滤掉表头并进行分词
header = data.first()
split_data= data.filter(lambda line: line != header).map(lambda x:x.split(","))
split_data.take(3)
# 求各个地区总的销售额和利润
# []中下标从0开始
# 提取出地区 销售额 利润的数据
q1_data = split_data.map(lambda x:(x[11],x[-4],x[-1]))
# q1_data.collect()
q1_data.take(3)
# 分别求各个地区总的销售额
# float转换字符串类型
split_data.map(lambda x:(x[11],float(x[-4]))).reduceByKey(lambda x,y:x+y).collect()
# 分别求各个地区总的利润
split_data.map(lambda x:(x[11],float(x[-1]))).reduceByKey(lambda x,y:x+y).collect()
# 一次性求各个地区总的销售额和利润
# (a,[x[0],x[1]])
# (b,[y[0],y[1]])
# lambda x,y:(x[0]+y[0],x[1]+y[1])
split_data.map(lambda x:(x[11],(float(x[-4]),float(x[-1])))).reduceByKey(lambda x,y:(x[0]+y[0],x[1]+y[1])).collect()
salesRDD = split_data.map(lambda x:(x[11],float(x[17])))
result_sales = salesRDD.reduceByKey(lambda x,y:x+y)
result_sales.collect()
profitRDD = split_data.map(lambda x:(x[11],float(x[20])))
result_profit = profitRDD.reduceByKey(lambda x,y:x+y)
result_profit.collect()
# 求各个类别的销售数量和平均折扣
# 注计算平均折扣时,不计算折扣为0的数据
# 求各个类别的销售数量
split_data.map(lambda x:(x[13],float(x[-3]))).reduceByKey(lambda x,y:x+y).collect()
# 求各个类别平均折扣
# lambda x:x[-2]!='0'过滤掉折扣为0的数据
# lambda x:sum(list(x))/len(x)计算平均折扣
split_data.filter(lambda x:x[-2]!='0').map(lambda x:(x[13],float(x[-2]))).groupByKey().mapValues(lambda x:sum(list(x))/len(x)).collect()
# 求根据客户消费金额进行排序,列出排名前10的客户名称
# ascending=False降序排列
split_data.map(lambda x:(x[6],float(x[-4]))).reduceByKey(lambda x,y:x+y).sortBy(lambda x:x[1],ascending=False).take(10)
# 求各个季度每个地区的总销售额,升序排列
# sortBy默认升序排列
# datetime.strptime(x[2],'%Y/%m/%d').month:使用"%Y/%m/%d"格式解析为日期时间对象,并提取出月份
# (datetime.strptime(x[2],'%Y/%m/%d').month-1)//3+1:通过计算月份来确定季度。首先,将月份减1,得到的结果再除以3取整数商,最后加1,即可得到季度。因为每个季度包含3个月,所以对月份减1再除以3可以将1-3月划分为第1季度,4-6月划分为第2季度,以此类推。
from datetime import datetime
split_data.map(lambda x:(((datetime.strptime(x[2],'%Y/%m/%d').month-1)//3+1,x[11]),float(x[-4]))).reduceByKey(lambda x,y:x+y).sortBy(lambda x:x[1]).collect()
# 求各个省/自治区的平均备货时间,降序排列
# 备货时间=发货日期-订单日期
# (datetime.strptime(x[3],'%Y/%m/%d')-datetime.strptime(x[2],'%Y/%m/%d')).days):使用"%Y/%m/%d"格式解析为日期时间对象,计算备货时间,并提取出天数
# .days()获取其天数
# ascending=False降序排列
from datetime import datetime
split_data.map(lambda x:(x[9],(datetime.strptime(x[3],'%Y/%m/%d')-datetime.strptime(x[2],'%Y/%m/%d')).days))\
.groupByKey().mapValues(lambda x:sum(list(x))/len(x))\
.sortBy(lambda x:x[1],ascending=False).collect()
4、结果
1、
2、
3、
4、
5、