基于Spark对消费者行为数据进行数据分析开发案例
原创/朱季谦
本文适合入门Spark RDD的计算处理。
在日常工作当中,经常遇到基于Spark去读取存储在HDFS中的批量文件数据进行统计分析的案例,这些文件一般以csv或者txt文件格式存在。例如,存在这样一份消费者行为数据,字段包括消费者姓名,年龄,性别,月薪,消费偏好,消费领域,购物平台,支付方式,单次购买商品数量,优惠券获取情况,购物动机。
基于这份消费者行为数据,往往会有以下一些分析目标:
- 用户统计学分析:针对性别、年龄等属性进行统计分析,了解消费者群体的组成和特征。
- 收入与购买行为的关系分析:通过比较月薪和单次购买商品数量之间的关系,探索收入水平对消费行为的影响。
- 消费偏好和消费领域的分析:查看不同消费者的消费偏好(例如性价比、功能性、时尚潮流等)和消费领域(例如家居用品、汽车配件、美妆护肤等),以了解他们的兴趣和偏好。
- 购物平台和支付方式的分析:研究购物平台(例如天猫、淘宝、拼多多等)和支付方式(例如微信支付、支付宝等)的选择情况,了解消费者在电商平台上的偏好。
- 优惠券获取情况和购物动机的关系:观察优惠券获取情况和购物动机之间的联系,探索消费者是否更倾向于使用优惠券进行购物。
针对这些需求,就可以使用Spark来读取文件后,进一步分析处理统计。
接下来,就是针对以上分析目标,设计一番Spark代码计算逻辑,由此可入门学习下Spark RDD常用用法。
获取一份具备以下字段的csv随机假样本,总共5246条数据,包括“消费者姓名,年龄,性别,月薪,消费偏好,消费领域,购物平台,支付方式,单次购买商品数量,优惠券获取情况,购物动机”。
Amy Harris,39,男,18561,性价比,家居用品,天猫,微信支付,10,折扣优惠,品牌忠诚
Lori Willis,33,女,14071,功能性,家居用品,苏宁易购,货到付款,1,折扣优惠,日常使用
Jim Williams,61,男,14145,时尚潮流,汽车配件,淘宝,微信支付,3,免费赠品,礼物赠送
Anthony Perez,19,女,11587,时尚潮流,珠宝首饰,拼多多,支付宝,5,免费赠品,商品推荐
......
将样本存放到项目目录为src/main/resources/consumerdata.csv,然后新建一个Scala的object类,创建一个main方法, 模拟从HDSF读取数据,然后通过.map(_.split(","))将csv文件每一行切割成一个数组形式的RDD
def main(args: Array[String]): Unit = {val conf = new SparkConf().setMaster("local").setAppName("consumer")val ss = SparkSession.builder().config(conf).getOrCreate()val filePath: String = "src/main/resources/consumerdata.csv"val consumerRDD = ss.sparkContext.textFile(filePath).map(_.split(","))
可以写一段代码打印看一下consumerRDD结构——
consumerRDD.foreach(x => {x.foreach(y => print(y +" "))println()})
打印结果如下——
这个RDD相当于把每一行当作里一个Array[]数组,第一行的Array0是消费者姓名,即Amy Harris,Array1是年龄,即39,以此类推。
消费者姓名 | 年龄 | 性别 | 月薪 | 消费偏好 | 消费领域 | 购物平台 | 支付方式 | 单次购买商品数量 | 优惠券获取情况 | 购物动机 |
---|---|---|---|---|---|---|---|---|---|---|
Amy Harris | 39 | 男 | 18561 | 性价比 | 家居用品 | 天猫 | 微信支付 | 10 | 折扣优惠 | 品牌忠诚 |
Lori Willis | 33 | 女 | 14071 | 功能性 | 家居用品 | 苏宁易购 | 货到付款 | 1 | 折扣优惠 | 日常使用 |
。。。 |
获取到该RDD后,就可以进行下一步的统计分析了。
一、统计消费者支付方式偏好分布
这行代码意思,x.apply(7)表示取每一行的第八个字段,相当数组Array[7],第八个字段是【支付方式】。
- map(x=>(x.apply(7),1))表示是对RDD里每一行出现过的支付方式字段设置为1个,例如,第一行把原本数组格式Array的RDD做了转换,生成(微信支付,1)格式的新RDD,表示用微信支付的用户出现了1次。
- reduceByKey(_ + _)表示按RDD的key进行聚合统计,表示统计微信支付出现的次数,支付宝出现的次数等。最后,通过
- sortBy(_._2,false)表示按照key-value当中的value进行倒序排序,false表示倒叙,true表示升序。
因此就可以按照以上格式,对文本数据里的每一个字段做相应分析,后文其他计算逻辑也是类似。
consumerRDD.map(x => (x.apply(7),1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印结果如下:
二、统计购物平台偏好分布
x.apply(5)表示取每一行的第六个字段,相当数组Array[5],第六个字段是【购物平台】。
同前文的【统计消费者支付方式偏好分布】一样,通过map(x=>(x.apply(5),1))生成(购物平台,1)格式的RDD,然后再通过reduceByKey算子针对相同的key做统计,最后倒序排序。
consumerRDD.map(x => (x.apply(5), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印结果——
三、统计购物偏好方式分布
x.apply(4)表示取每一行的第五个字段,相当数组Array[4],第五个字段是【消费领域】。
consumerRDD.map(x => (x.apply(4), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印结果:
四、统计购物动机分布
x.apply(10)表示取每一行的第十个字段,相当数组Array[10],第10个字段是【购物动机】。
consumerRDD.map(x => (x.apply(10), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印结果——
五、消费者年龄分布
该需求通过将RDD映射成DataFrame数据集,方便用SQL语法处理,按照年龄区间分区,分别为"0-20","21-30","31-40"
......这个分区字符串名,就相当key,value表示落在该分区的用户数量。这时,就可以分组做聚合统计了,统计出各个年龄段的消费者数量。
//取出consumerRDD每一行数组需要的字段
val rowRDD = consumerRDD.map{x => Row(x.apply(0),x.apply(1).toInt,x.apply(2),x.apply(3).toInt,x.apply(4),x.apply(5),x.apply(6),x.apply(7),x.apply(8).toInt,x.apply(9),x.apply(10))
}//设置字段映射
val schema = StructType(Seq(StructField("consumerName", StringType),StructField("age", IntegerType),StructField("gender", StringType),StructField("monthlyIncome", IntegerType),StructField("consumptionPreference", StringType),StructField("consumptionArea", StringType),StructField("shoppingPlatform", StringType),StructField("paymentMethod", StringType),StructField("quantityOfItemsPurchased", IntegerType),StructField("couponAcquisitionStatus", StringType),StructField("shoppingMotivation", StringType)))
val df = ss.createDataFrame(rowRDD, schema).toDF()
//按年龄分布计算
val agedf = df.withColumn("age_range",when(col("age").between(0, 20), "0-20").when(col("age").between(21, 30), "21-30").when(col("age").between(31, 40), "31-40").when(col("age").between(41, 50), "41-50").when(col("age").between(51, 60), "51-60").when(col("age").between(61, 70), "61-70").when(col("age").between(81, 90), "81-90").when(col("age").between(91, 100), "91-100").otherwise("Unknow")
)
//分组统计
val result = agedf.groupBy("age_range").agg(count("consumerName").alias("Count")).sort(desc("Count"))
result.show()
打印结果:
六、统计年龄分布
类似年龄分布的操作。
val sexResult = agedf.groupBy("gender").agg(count("consumerName").alias("Count")).sort(desc("Count"))
sexResult.show()
打印结果:
除了以上的统计分析案例之外,还有优惠券获取情况和购物动机的关系、消费领域方式等统计,可以进一步拓展分析。
本文基于分析消费者行为数据,可以入门学习到,Spark如何读取样本文件,通过map(_.split(","))处理样本成一个数组格式的RDD,基于该RDD,可以进一步通过map、reduceByKey、groupBy等算子做处理与统计,最后获取该样本的信息价值。
相关文章:

基于Spark对消费者行为数据进行数据分析开发案例
原创/朱季谦 本文适合入门Spark RDD的计算处理。 在日常工作当中,经常遇到基于Spark去读取存储在HDFS中的批量文件数据进行统计分析的案例,这些文件一般以csv或者txt文件格式存在。例如,存在这样一份消费者行为数据,字段包括消费…...

Docker镜像制作与推送
目录 Docker镜像制作 搭建私服 将本地镜像推送到私有库 Docker镜像制作 以创建一个新ubuntu镜像,并安装vim命令示例 运行一个ubuntu镜像,发现在镜像里面无法使用vim命令,因为该ubuntu镜像只包括了其最基本的内核命令 [rootlocalhost ~]…...

Pandas时序数据分析实践—基础(1)
目录 1. Pandas基本结构2. Pandas数据类型2.1. 类型概述2.1.1. 整数类型(int):2.1.2. 浮点数类型(float):2.1.3. 布尔类型(bool):2.1.4. 字符串类型(object&a…...

5.C转python
新始: 13.列表可被改变(数据),元组不可被改变(数据),二者皆与C中的数组的大致相同 14.创建列表方法: 1.一个[ ]就是一个空的列表 2.使用list函数来创建列表 如: 15.可以在[ ]内部指定列表的初始值,打印方法: 如: 16.在python中,在同一个列表中,可以放不同类型的变量(也可…...
输出SearchFacesResponse对象的JSON格式字符串回包乱码解决方案
输出SearchFacesResponse对象的JSON格式字符串设置响应内容类型为"application/json;charsetutf-8"获取响应的字符输出流将SearchFacesResponse对象转化为JSON字符串并输出。 代码片段 System.out.println(SearchFacesResponse.toJsonString(resp)); response.setC…...

P7 链表 链表头前方插入新节点
目录 前言 01 链表头插入数据 示例代码 02 指定节点前方插入新节点 测试代码 前言 🎬 个人主页:ChenPi 🐻推荐专栏1: 《C》✨✨✨ 🔥 推荐专栏2: 《 Linux C应用编程(概念类)_ChenPi的博客-CSDN博客》✨…...
SCAU:主对角线上的元素之和
主对角线上的元素之和 Time Limit:1000MS Memory Limit:65535K 题型: 编程题 语言: G;GCC 描述 输入一个3行4列的整数矩阵,计算并输出主对角线上的元素之和输入格式 3行4列整数矩阵输出格式 主对角线上的元素之和输入样例 1 2 3 4 5 6 7 8 9 10 11 12输出…...
c语言——简单客户端demo
以下是一个简单的C语言客户端示例,用于连接到服务器并发送和接收数据: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h…...
日志检索场景ES->Doris迁移最佳实践:函数篇
函数列表 函数:term函数功能说明:查询某个字段里含有某个关键词的文档参数说明:返回值说明:ES使用示例: {"query": {"term": {"title": "blog"}} }Doris使用示例…...

【高效开发工具系列】jackson入门使用
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

深入理解网络非阻塞 I/O:NIO
🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任 Java 开发,CSDN 优质创作者 📖 推荐专栏:Spring、MySQL、Nacos、Java,后续其他专栏会持续优化更新迭代 🌲文章所在专栏&…...

Hdoop学习笔记(HDP)-Part.07 安装MySQL
目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …...

[数据结构]HashSet与LinkedHashSet的底层原理学习心得
我们区分list和set集合的标准是三个:有无顺序,可否重复,有无索引。 list的答案是:有顺序,可重复,有索引。这也就是ArrayList和LinkedList的共性 set的答案是:顺序内部再区分,不可以重复…...
使用unity开发Pico程序,场景中锯齿问题
1、问题 使用unity【非HDR】开发Pico程序,场景中锯齿问题,设置了unity的抗锯齿和渲染方式,及悬挂抗锯齿的脚本,都不能很好的解决项目中图片、文字的锯齿问题,通过摸索找到了妥善的方法 1、修改项目中图片的 GenerateMIpMaps 为勾…...

Spring | Spring的基本应用
目录: 1.什么是Spring?2.Spring框架的优点3.Spring的体系结构 (重点★★★) :3.1 Core Container (核心容器) ★★★Beans模块 (★★★) : BeanFactoryCore核心模块 (★★★) : IOCContext上下文模块 (★★★) : ApplicationContextContext-support模块 (★★★)SpE…...
项目开发维护技术文档(梳理总结中)
目录 项目名称——惠誉灵境 一、项目背景 二、架构设计 1.技术栈 2.架构图 3.代码结构 三、模块划分 1.平台首页 2.登录模块 3.系统模块 (1)系统首页 (2)组织架构 (3)权限管控 ①角色管理 (4&am…...

【接口测试】Apifox实用技巧干货分享
前言 不知道有多少人和我有着这样相似的经历:从写程序只要不报错就不测试😊,到写了程序若是有bug就debug甚至写单元测试,然后到了真实开发场景,大哥和你说,你负责的功能模块的所有接口写完要测试一遍无误在…...
车联网架构设计(一)_消息平台的搭建
车联网是物联网的一个主要应用方向,车辆通过连接车联网平台,实时进行消息的交互,平台可以提供车辆远程控制,故障检测,车路协同等各方面的功能。 我在车联网行业从事了很长时间的技术工作,参与了整个车联网…...

(蓝桥杯)1125 第 4 场算法双周赛题解+AC代码(c++/java)
题目一:验题人的生日【算法赛】 验题人的生日【算法赛】 - 蓝桥云课 (lanqiao.cn) 思路: 1.又是偶数,又是质数,那么只有2喽 AC_Code:C #include <iostream> using namespace std; int main() {cout<<2;return 0; …...

也可Adobe Animate
Animate CC 由原Adobe Flash Professional CC 更名得来,2015年12月2日:Adobe 宣布Flash Professional更名为Animate CC,在支持Flash SWF文件的基础上,加入了对HTML5的支持。并在2016年1月份发布新版本的时候,正式更名为…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...