当前位置: 首页 > news >正文

基于Spark对消费者行为数据进行数据分析开发案例

原创/朱季谦

image

本文适合入门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()})

打印结果如下——

image

这个RDD相当于把每一行当作里一个Array[]数组,第一行的Array0是消费者姓名,即Amy Harris,Array1是年龄,即39,以此类推。

消费者姓名年龄性别月薪消费偏好消费领域购物平台支付方式单次购买商品数量优惠券获取情况购物动机
Amy Harris3918561性价比家居用品天猫微信支付10折扣优惠品牌忠诚
Lori Willis3314071功能性家居用品苏宁易购货到付款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)

打印结果如下:

image

二、统计购物平台偏好分布

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)

打印结果——

image

三、统计购物偏好方式分布

x.apply(4)表示取每一行的第五个字段,相当数组Array[4],第五个字段是【消费领域】。

consumerRDD.map(x => (x.apply(4), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)

打印结果:

image

四、统计购物动机分布

x.apply(10)表示取每一行的第十个字段,相当数组Array[10],第10个字段是【购物动机】。

consumerRDD.map(x => (x.apply(10), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)

打印结果——

image

五、消费者年龄分布

该需求通过将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()

打印结果:

image

六、统计年龄分布

类似年龄分布的操作。

val sexResult = agedf.groupBy("gender").agg(count("consumerName").alias("Count")).sort(desc("Count"))
sexResult.show()

打印结果:

image

除了以上的统计分析案例之外,还有优惠券获取情况和购物动机的关系、消费领域方式等统计,可以进一步拓展分析。

本文基于分析消费者行为数据,可以入门学习到,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语言客户端示例&#xff0c;用于连接到服务器并发送和接收数据&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h…...

日志检索场景ES->Doris迁移最佳实践:函数篇

函数列表 函数&#xff1a;term函数功能说明&#xff1a;查询某个字段里含有某个关键词的文档参数说明&#xff1a;返回值说明&#xff1a;ES使用示例&#xff1a; {"query": {"term": {"title": "blog"}} }Doris使用示例&#xf…...

【高效开发工具系列】jackson入门使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

深入理解网络非阻塞 I/O:NIO

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…...

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集合的标准是三个&#xff1a;有无顺序&#xff0c;可否重复&#xff0c;有无索引。 list的答案是&#xff1a;有顺序&#xff0c;可重复&#xff0c;有索引。这也就是ArrayList和LinkedList的共性 set的答案是&#xff1a;顺序内部再区分,不可以重复&#xf…...

使用unity开发Pico程序,场景中锯齿问题

1、问题 使用unity【非HDR】开发Pico程序&#xff0c;场景中锯齿问题&#xff0c;设置了unity的抗锯齿和渲染方式,及悬挂抗锯齿的脚本&#xff0c;都不能很好的解决项目中图片、文字的锯齿问题&#xff0c;通过摸索找到了妥善的方法 1、修改项目中图片的 GenerateMIpMaps 为勾…...

Spring | Spring的基本应用

目录: 1.什么是Spring&#xff1f;2.Spring框架的优点3.Spring的体系结构 (重点★★★) :3.1 Core Container (核心容器) ★★★Beans模块 (★★★) : BeanFactoryCore核心模块 (★★★) : IOCContext上下文模块 (★★★) : ApplicationContextContext-support模块 (★★★)SpE…...

项目开发维护技术文档(梳理总结中)

目录 项目名称——惠誉灵境 一、项目背景 二、架构设计 1.技术栈 2.架构图 3.代码结构 三、模块划分 1.平台首页 2.登录模块 3.系统模块 &#xff08;1&#xff09;系统首页 &#xff08;2&#xff09;组织架构 &#xff08;3&#xff09;权限管控 ①角色管理 &#xff08;4&am…...

【接口测试】Apifox实用技巧干货分享

前言 不知道有多少人和我有着这样相似的经历&#xff1a;从写程序只要不报错就不测试&#x1f60a;&#xff0c;到写了程序若是有bug就debug甚至写单元测试&#xff0c;然后到了真实开发场景&#xff0c;大哥和你说&#xff0c;你负责的功能模块的所有接口写完要测试一遍无误在…...

车联网架构设计(一)_消息平台的搭建

车联网是物联网的一个主要应用方向&#xff0c;车辆通过连接车联网平台&#xff0c;实时进行消息的交互&#xff0c;平台可以提供车辆远程控制&#xff0c;故障检测&#xff0c;车路协同等各方面的功能。 我在车联网行业从事了很长时间的技术工作&#xff0c;参与了整个车联网…...

(蓝桥杯)1125 第 4 场算法双周赛题解+AC代码(c++/java)

题目一&#xff1a;验题人的生日【算法赛】 验题人的生日【算法赛】 - 蓝桥云课 (lanqiao.cn) 思路&#xff1a; 1.又是偶数&#xff0c;又是质数&#xff0c;那么只有2喽 AC_Code:C #include <iostream> using namespace std; int main() {cout<<2;return 0; …...

也可Adobe Animate

Animate CC 由原Adobe Flash Professional CC 更名得来&#xff0c;2015年12月2日&#xff1a;Adobe 宣布Flash Professional更名为Animate CC&#xff0c;在支持Flash SWF文件的基础上&#xff0c;加入了对HTML5的支持。并在2016年1月份发布新版本的时候&#xff0c;正式更名为…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...