SparkSQL内置函数

我们在操作DataFrame的方法中可以随时调用内置函数进行业务需要的处理,这对于我们构建附件的业务逻辑而言是可以极大的减少不必要的时间消耗,让我们聚焦在数据分析上,有助于提高工程师的生产力。

DataFrame天生就是"A distributed collection of data organized into named columns.",这就为数据的复杂分析建立了坚实的基础并提供了极大的方便性

Spark SQL 函数

类别函数举例
聚合函数countDistinct、sumDistinct
集合函数sort_array、explode
日期、时间函数hour、quarter、next_day
数字函数asin、atan、sqrt、round
开窗函数row_number
字符串函数concat、format_number、regexp_extract
其他函数isNaN、sha、randn、callUDF

统计每日uv和销售额

根据每天的用户访问日志和用户购买日志,统计每日的uv和销售额

UV:每天都有很多用户来访问,但是每个用户可能每天都会访问很多次,所以uv,指的是对用户进行去重以后的访问次数(去重统计总数),这里使用内置函数 countDistinct

  1. 首先,对DataFrame调用groupBy()方法,对某一列进行分组
  2. 然后调用agg()方法,第一个参数,必须必须必须传入之前在groupBy()方法中出现的字段
  3. 第二个参数,传入countDistinct('userid),sum,first等,Spark提供的内置函数
  4. 内置函数中,传入的参数,也是用单引号作为前缀的
userAccessLogRowDF.groupBy("date")
  .agg('date,countDistinct('userid))
  .map(row => Row(row(1),row(2)))
  .collect()
  .foreach(println)
//开始进行每日销售额的统计
userSaleRowDF.groupBy("date")
  .agg('date,sum('sale))
  .map(row => Row(row(1),row(2)))
  .collect()
  .foreach(println)

完整代码

Scala版本countDistinct代码

package com.carve.spark
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.types.IntegerType
import org.apache.spark.sql.functions._
object DailyUV {
  def main(args: Array[String]){
   val conf = new SparkConf()
    .setMaster("local")  
    .setAppName("DailyUV")
    val sc = new SparkContext(conf)
    val sqlContext = new SQLContext(sc)
   
    // 要使用Spark SQL的内置函数,就必须在这里导入SQLContext下的隐式转换
   import sqlContext.implicits._
   
   // 构造用户访问日志数据,并创建DataFrame
    
   // 模拟用户访问日志,日志用逗号隔开,第一列是日期,第二列是用户id
   val userAccessLog = Array(
        "2015-10-01,1122",
        "2015-10-01,1122",
        "2015-10-01,1123",
        "2015-10-01,1124",
        "2015-10-01,1124",
        "2015-10-02,1122",
        "2015-10-02,1121",
        "2015-10-02,1123",
        "2015-10-02,1123");
    val userAccessLogRDD = sc.parallelize(userAccessLog, 5)
    
    // 将模拟出来的用户访问日志RDD,转换为DataFrame
    // 首先,将普通的RDD,转换为元素为Row的RDD
    val userAccessLogRowRDD = userAccessLogRDD
    .map{ log => Row(log.split(",")(0), log.split(",")(1).toInt)}
    // 构造DataFrame的元数据
    val structType = StructType(Array(
        StructField("date", StringType, true),
        StructField("userid", IntegerType, true)))  
    // 使用SQLContext创建DataFrame
    val userAccessLogRowDF = sqlContext.createDataFrame(userAccessLogRowRDD, structType) 
    
    userAccessLogRowDF.groupBy("date")
    .agg('date, countDistinct('userid))
    .map { row => Row(row(1), row(2)) }
    .collect()
    .foreach(println)
  }
}

Scala版本sum代码

package com.carve.spark
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.types.DoubleType
import org.apache.spark.sql.functions._
object DailySale {
  def main(args: Array[String]){
   val conf = new SparkConf()
    .setMaster("local")  
    .setAppName("DailyUV")
    val sc = new SparkContext(conf)
    val sqlContext = new SQLContext(sc)
   
   import sqlContext.implicits._
   
   // 模拟数据
   val userSaleLog = Array("2015-10-01,55.05,1122",
        "2015-10-01,23.15,1133",
        "2015-10-01,15.20,",
        "2015-10-02,56.05,1144",
        "2015-10-02,78.87,1155",
        "2015-10-02,113.02,1123")
   val userSaleLogRDD = sc.parallelize(userSaleLog, 5)
   
   // 进行有效销售日志的过滤
   val filteredUserSaleLogRDD = userSaleLogRDD
   .filter {log =>if (log.split(",").length == 3) true else false }
   
   val userSaleLogRowRDD = filteredUserSaleLogRDD
   .map { log => Row(log.split(",")(0), log.split(",")(1).toDouble) }
   
   val structType = StructType(Array(
       StructField("date", StringType, true),
       StructField("sale_amount", DoubleType, true)))
   
   val userSaleLogDF = sqlContext.createDataFrame(userSaleLogRowRDD, structType)
   userSaleLogDF.groupBy("date")
   .agg('date, sum('sale_amount))
   .map{ row => Row(row(1),row(2)) }
   .collect()
   .foreach(println)
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上行舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值