广电用户画像分析之数据基本分析与预处理

引言

数据分析在今天的数字化时代变得越来越重要,尤其是对于媒体行业来说。了解用户的收视行为和对媒体的偏好可以帮助媒体公司制定更有效的营销策略和优化内容推荐。本文将介绍如何使用Spark进行广电数据的基本分析和预处理,以便获取有关用户收视行为的有用信息。

关于数据集字段的基本分析和数据集下载见于此处:
https://blog.csdn.net/kilig_CSM/article/details/131281211?spm=1001.2014.3001.5501

探索用户收视行为数据表media_index并进行基本分析

统计媒体观看时长的最大值和最小值:通过查询表中的duration字段,将其转换为小时和秒,并计算出最大值和最小值。这可以帮助了解用户观看媒体的时间范围。

统计无效的观看记录:通过查询表中的origin_time、end_time和res_type字段,找出观看记录中origin_time和end_time以"%00"结尾且res_type为0的记录。这可以帮助识别无效或错误的观看记录。

输出总记录数和无效观看记录数:统计表中的总记录数和无效观看记录数,并将结果打印到控制台上。这可以提供关于数据完整性和质量的信息。

总体而言,这个类旨在对媒体数据表进行基本的统计和分析,以了解数据的特征和质量,并可能用于后续的数据处理和决策。

思路:

导入所需的库和模块:导入org.apache.spark.sql.SparkSession库,以及org.apache.spark.sql.functions._模块,后者包含了Spark SQL中常用的函数。

创建SparkSession:使用SparkSession.builder()创建一个SparkSession实例。设置应用程序的名称为"MediaAnalyse",将Spark的master节点设置为本地模式(local[*]),使用所有可用的本地线程进行计算。同时启用Hive支持(.enableHiveSupport()),以便通过Hive访问数据。最后,通过.getOrCreate()获取或创建SparkSession实例。

设置日志级别:使用spark.sparkContext.setLogLevel(“WARN”)将Spark的日志级别设置为"WARN",以减少日志输出。

创建main()函数:主要的代码逻辑将放置在main()函数中。

读取媒体数据表:使用spark.table(“user_project.media_index”)获取名为user_project.media_index的Hive表的数据。

统计时长的最大值和最小值:通过执行SQL查询语句spark.sql(“select max(duration)/(10006060) as maxDuration_h,min(duration)/1000 as minDuration_s from user_project.media_index;”)获取时长字段duration的最大值和最小值,并使用show()方法将结果显示在控制台上。

统计无效观看记录:通过执行SQL查询语句spark.sql(“select origin_time,end_time,res_type from user_project.media_index where origin_time like ‘%00’ and end_time like ‘%00’ limit 10;”)筛选出origin_time和end_time字段以"%00"结尾且res_type字段为0的记录,并使用show()方法将结果显示在控制台上。

使用count()方法统计总记录数,并使用println()方法将结果打印出来。

使用filter()方法筛选出无效观看记录,并使用count()方法统计数量,并使用println()方法将结果打印出来。

在main()函数的最后,执行代码逻辑并运行应用程序。

核心代码:

// 读取收视数据表

val media = spark.table(“user_project.media_index”)

// 统计时长duration的最值

spark.sql(“select max(duration)/(10006060) as maxDuration_h, min(duration)/1000 as minDuration_s from user_project.media_index;”).show()

// 统计无效的观看记录

spark.sql(“select origin_time, end_time, res_type from user_project.media_index where origin_time like ‘%00’ and end_time like ‘%00’ limit 10;”).show()

// 输出总记录数

println(“总记录数:” + media.count())

// 输出无效观看记录数

println(“无效观看记录:” + media.filter(“res_type=0 and origin_time like ‘%00’ and end_time like ‘%00’”).count())

完整代码

package code.anaylse

import org.apache.spark.sql.SparkSession
object BasicAnaylse {
  val spark=SparkSession.builder().appName("BasicAnalyse")
    .master("local[*]")
    .enableHiveSupport()
    .getOrCreate()
  //
  spark.sparkContext.setLogLevel("WARN")
  def main(args: Array[String]): Unit = {
    //探索每个表中的重复记录表和空值记录数
    val tableName = Array("media_index","mediamatch_userevent","mediamatch_usermsg","mmconsume_billevents","order_index")
    var i = "";
    for(i<-tableName){
      Analyse(i)
    }

//    val mediamatch_userevent = spark.table("user_project.mediamatch_userevent")
//    mediamatch_userevent.show(false)
  }
  def Analyse(tableName:String): Unit ={
    val data = spark.table("user_project."+tableName)
    print(tableName+"表数据:"+data.count())
    print(tableName+"表phone_no字段为空数:"+(data.count()-data.select("phone_no").na.drop().count))

  }
}

探索各个表中指定字段的数据和用户观看每个节目的时长

该类使用Spark的SQL函数进行统计分析。首先,使用max函数计算媒体表中观看时长字段"duration"的最大值,并将结果显示出来。然后,使用selectExpr方法同时计算媒体表中观看时长的最大值和最小值,并将结果显示出来。

思路:

定义需要分析的表名,包括"media_index"、“order_index”、“mmconsume_billevents”、“mediamatch_userevent"和"mediamatch_usermsg”,将它们存储在一个数组中。

使用spark.table方法读取Hive中的表数据,并分别赋值给对应的DataFrame变量。

使用import org.apache.spark.sql.functions._导入SQL函数,以便在后续的分析中使用。

使用max函数计算媒体表中观看时长字段"duration"的最大值,并通过show方法显示结果。

使用selectExpr方法同时计算媒体表中观看时长的最大值和最小值,并通过show方法显示结果。

定义一个AllAnalyse方法,用于对指定字段进行分析。该方法接收字段名和数据集作为参数,首先使用distinct方法获取字段的唯一值,并通过show方法显示结果,然后使用groupBy和count方法对字段进行分组统计,并通过show方法显示结果。

程序执行结束。

核心代码:

import org.apache.spark.sql.functions._

// 读取媒体表数据

val media_index = spark.table(“user_project.media_index”)

// 使用max函数计算观看时长字段"duration"的最大值,并通过show方法显示结果

media_index.select(max(“duration”)).show()

// 使用selectExpr方法同时计算观看时长的最大值和最小值,并通过show方法显示结果

media_index.selectExpr(“max(duration)/1000/60/60”, “min(duration)/1000/60/60”).show()


完整代码

package code.anaylse

import org.apache.spark.sql.types.IntegerType
import org.apache.spark.sql.{DataFrame, SparkSession}

object TotalAnalyes {
  val spark = SparkSession.builder().appName("MediaAnalyse")
    .master("local[*]")
    .enableHiveSupport()
    .getOrCreate()
  //
  spark.sparkContext.setLogLevel("WARN")

  def main(args: Array[String]): Unit = {

    /* 数据库user_project 中的五个表
    "media_index","order_index","mmconsume_billevents"
    "mediamatch_userevent","mediamatch_usermsg"
     */
    val media_index = spark.table("user_project.media_index")
    val order_index = spark.table("user_project.order_index")
    val mmconsume_billevents = spark.table("user_project.mmconsume_billevents")
    val mediamatch_userevent = spark.table("user_project.mediamatch_userevent")
    val mediamatch_usermsg = spark.table("user_project.mediamatch_usermsg")

    /* 获取个表中下列字段的内容
      "run_name","owner_code","owner_name","sm_name"
     */
    /*print("media_index表:")
    AllAnalyse("owner_code",media_index)
    AllAnalyse("owner_name",media_index)
    AllAnalyse("sm_name",media_index)

    print("usermsg表:")
    AllAnalyse("owner_code",mediamatch_usermsg)
    AllAnalyse("owner_name",mediamatch_usermsg)
    AllAnalyse("sm_name",mediamatch_usermsg)
    AllAnalyse("run_name",mediamatch_usermsg)

    print("billevents表:")
    AllAnalyse("owner_code",mmconsume_billevents)
    AllAnalyse("owner_name",mmconsume_billevents)
    AllAnalyse("sm_name",mmconsume_billevents)

    print("userevent表:")
    AllAnalyse("owner_code",mediamatch_userevent)
    AllAnalyse("owner_name",mediamatch_userevent)
    AllAnalyse("sm_name",mediamatch_userevent)
    AllAnalyse("run_name",mediamatch_userevent)*/
    /*
      统计用户观看每个节目的时长
     */
    import org.apache.spark.sql.functions._
    //    media_index.withColumn("logTime",max("duration").cast(IntegerType)/1000/60/60)
    //      .withColumn("minTime",min("duration").cast(IntegerType)/1000/60/60).show()
    media_index.select(max("duration")).show()
    media_index.selectExpr("max(duration)/1000/60/60", "min(duration)/1000/60/60").show()
  }

  def AllAnalyse(col: String, data: DataFrame): Unit = {
    data.select(col).distinct().show(false)
    data.groupBy(col).count().show()
  }
}

对五个数据表中的数据进行预处理

对数据库中的五个表进行数据清洗和筛选,并将处理后的结果保存到Hive表中。核心目的是处理和存储经过筛选和清洗后的数据,以便后续的分析和使用。

思路:

使用spark.table方法读取数据库中的五个表,分别赋值给相应的变量:media_index、order_index、mmconsume_billevents、mediamatch_userevent和mediamatch_usermsg。

定义筛选规则,包括owner_name、sm_name和run_name的条件过滤条件。

进行数据清洗和筛选,根据定义的筛选规则对各个表进行过滤,并使用distinct()方法去除重复数据。

调用saveData函数,将清洗和筛选后的结果保存到对应的Hive表中,函数接受两个参数:要保存的数据和目标表名。

重复步骤6和步骤7,对剩余的表进行清洗和保存操作。

完成数据的清洗和存储后,程序执行结束。

总体思路是读取数据库中的表数据,按照定义的筛选规则进行数据清洗和过滤,然后将处理后的结果保存到Hive表中,以便后续的分析和使用。

核心代码:

/*数据存储 */

saveData(mediamatch_userevent.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct(),“mediamatch_userevent”)

saveData(mediamatch_usermsg.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct(),“mediamatch_usermsg”)

saveData(order_index.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct(),“order_index”)

saveData(mmconsume_billevents.filter(ownerFilter).filter(smNameFilter).distinct(),“mmconsume_billevents”)

saveData(media_index.filter(ownerFilter).filter(smNameFilter).filter(“duration>4000 and duration <21600000”)

.filter(“res_type != ‘0’ and origin_time not rlike ‘00 ′ a n d e n d t i m e n o t r l i k e ′ 00 ' and end_time not rlike '00 andendtimenotrlike00’”).distinct(),“media_index”)

完整代码

package code.process


import org.apache.derby.impl.sql.compile.TableName
import org.apache.spark.sql.{DataFrame, SparkSession}

object processData {
 def main(args: Array[String]): Unit = {
   System.setProperty("HADOOP_USER_NAME", "root")
   val spark = SparkSession.builder().appName("Process")
     .master("local[*]")
     .enableHiveSupport()
     .getOrCreate()
   //
   spark.sparkContext.setLogLevel("WARN")

   /* 数据库user_project 中的五个表
   "media_index","order_index","mmconsume_billevents"
   "mediamatch_userevent","mediamatch_usermsg"
    */
   val media_index = spark.table("user_project.media_index")
   val order_index = spark.table("user_project.order_index")
   val mmconsume_billevents = spark.table("user_project.mmconsume_billevents")
   val mediamatch_userevent = spark.table("user_project.mediamatch_userevent")
   val mediamatch_usermsg = spark.table("user_project.mediamatch_usermsg")

   /**
     * 筛选规则(适用范围 :全表)
     */
   val ownerFilter = "owner_name != 'EA级' and owner_name != 'EC级' " +
                     "and owner_name != 'EB级' and owner_name != 'ED级' " +
                     "and owner_name != 'EE级' and " +
                     "owner_code != '02' and owner_code != '09' and " +
                     "owner_code != '10'"
   val smNameFilter = "sm_name == '珠江宽频' or sm_name == '数字电视' or " +
                       "sm_name == '互动电视' or sm_name == '甜果电视'"

   /**
     * 筛选规则(适用范围 :表mediamatch_userevent,表mediamatch_usermsg,表order_index)
     */
   val runNameFilter = " run_name == '正常' or run_name == '主动暂停' or " +
                       "run_name == '主动销号' or run_name == '欠费暂停' "


   /**
     * 数据清洗
     */
   /*mediamatch_userevent.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct().show(10)
   mediamatch_usermsg.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct().show(10)
   order_index.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct().show(10)
   mmconsume_billevents.filter(ownerFilter).filter(smNameFilter).distinct().show(10)

   // res_type != '0' and origin_time not rlike '00$' and end_time not rlike '00$'
   // res_type != '0' and origin_time not like '00$' and end_time not like '00$'
   media_index.filter(ownerFilter).filter(smNameFilter).filter("duration>4000 and duration <21600000")
     .filter("res_type != '0' and origin_time not rlike '00$' and end_time not rlike '00$'").distinct().show(10)*/

   /**
     *   数据存储
     */
   saveData(mediamatch_userevent.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct(),"mediamatch_userevent")
   saveData(mediamatch_usermsg.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct(),"mediamatch_usermsg")
   saveData(order_index.filter(ownerFilter).filter(smNameFilter).filter(runNameFilter).distinct(),"order_index")
   saveData(mmconsume_billevents.filter(ownerFilter).filter(smNameFilter).distinct(),"mmconsume_billevents")
   saveData(media_index.filter(ownerFilter).filter(smNameFilter).filter("duration>4000 and duration <21600000")
     .filter("res_type != '0' and origin_time not rlike '00$' and end_time not rlike '00$'").distinct(),"media_index")
 }

 def saveData(data:DataFrame,tableName:String): Unit ={
   data.write.saveAsTable("processData."+tableName)
 }
}

总结:

本文介绍了使用Spark进行媒体数据分析和预处理的基本方法。通过对用户收视行为数据表的分析,我们可以了解用户的观看时间范围和无效观看记录。同时,通过对各个表中指定字段的数据进行分析,我们可以获取有关观看时长和其他字段的统计信息。最后,我们对数据进行了清洗和筛选,并将处理后的结果保存到Hive表中,以便后续的分析和使用。如有帮助请点赞收藏.

posted @ 2023-09-16 23:29  冷月半明  阅读(84)  评论(0编辑  收藏  举报  来源