2.Scala读取文件和数据处理,Rdd,DataFrame,DataSet理解

读取文件,Rdd,DataFrame,DataSet理解

Rdd   :    算子,或者我们可以将其理解为一个数组(虽然它不是数组),想象它就像一个长方形的容器,里面就单纯的存储着数据 

DataFrame  :  将Rdd比作长方形的容器,DataFrame就是多个长方形的容器拼接组成,也就是将rdd加上表格化就是dataframe

DataSet  :,DataSet有很多的类型,相当于是由rdd经过不同类型组合起来的,其中一种类型就是DataFrame, 及Dataset[Row]=DataFrame

三者转换:

1).RDD转换DataFrame或者Dataset
转换DataFrame时,定义Schema信息,加上表格化
转换为Dataset时,不仅需要Schema信息,还需要RDD数据类型为CaseClass类型
2)Dataset或DataFrame转换RDD
由于Dataset或DataFrame底层就是RDD,所以直接调用rdd函数即可转换
dataframe.rdd 或者dataset.rdd
3)DataFrame与Dataset之间转换
由于DataFrame为Dataset特例,所以Dataset直接调用toDF函数转换为DataFrame
当将DataFrame转换为Dataset时,使用函数as[Type],指定CaseClass类型即可。


下面原文更清楚链接:https://blog.csdn.net/ZGL_cyy/article/details/119865313

scala读取Hadoop数据库

// 创建SparkSession对象
val spark = SparkSession.builder().appName("aaa").config("spark.master", "local")
  // 设置Hadoop文件系统
  .config("spark.hadoop.fs.defaultFS", "hdfs://192.168.52.147:8020").getOrCreate()
// 从HDFS中读取数据
val rdd = spark.sparkContext.textFile("hdfs://192.168.52.146:9000/data/userbehavior/UserBehavior.csv")

 scala读取本地文件

读取本地文件有3种方法,它们之间也有很大的差异

1.使用spark.sparkContext.textfile,这样读取的文件后aaa是一个rdd,方便进行api处理

val conf = new SparkConf().setAppName("etldemo").setMaster("local")
val spark = SparkSession.builder().config(conf)
  .enableHiveSupport() //------Hive支持
  .getOrCreate()
val aaa = spark.sparkContext.textFile("D://File/wechat/test.log")

2. 使用spark.read.csv,这样读取文件是一个dataframe,使用read.csv获得的数据spark对其进行了处理,它将数据根据一列一列分割开了,变成一个表格化

  val df = spark.read.csv("hdfs://192.168.52.147:8020/app/data/exam/meituan_waimai_meishi.csv") 

val df = spark.read.option("header", "true").csv("hdfs://192.168.52.147:8020/app/data/exam/meituan_waimai_meishi.csv")    //它可以加上.option("header", "true")为数据是否加上表头,true为保留表头,false去除表头,

 3.使用.read.text 方法读取文本文件返回一个 DataFrame。这个 DataFrame 的每一行对应文本文件中的一行。就只是读取了文件,没有任何处理,数据就是一行一坨在一起的。

 val df = spark.read.text("hdfs://192.168.52.147:8020/app/data/exam/meituan_waimai_meishi.csv") //

 数据处理

Rdd的Api处理,先将DataFrame转换为RDD,或者本来就是Rdd

.map(x=>(x(1),x(2))                        ---将数据中的第二个和第三个数据拿出来,可以衍生在map里面进行处理数据如相加或者乘除

.filter(!_.startsWith("sp_id"))           ---过滤掉以"spu_id"开头的行

.map(_.split(",",-1))                         ---分割每行,保留所有尾随的空字符串

同一种目的的reduceByKey,reduce,groupBy的不同用法

val keyValuePairs = aaa.rdd.map(arr => (arr(2), 1)).reduceByKey(_ + _).foreach(println)
//生成了一个以该元素的第三个元素为键、以1为值的键值对,将具有相同键的所有值相加。

val ccc=aaa.rdd.map(x=>(x (2),x(0),x(1),1)).reduce((x,y)=>(x._1,x._2,x._3,x._4+y._4))
//将filteredAndSplitRDD中的每个元素映射为一个元组,元组的第一个元素为x(2),第二个元素为x(0),第三个元素为x(1),第四个元素为1

val ddd=aaa.rdd.map(x=>(x (2),x(0),x(1))).groupBy(x=>x._1).map(x=>(x._1,x._2.toList.size)).foreach(print) 
 //将aaa中的每个元素映射为一个元组,元组的第一个元素为x(2),第二个元素为x(0),第三个元素为x(1)

 

val dd=rdd.map(x=>(x(1),x(2).toDouble))
  // 将每个元组映射为一个元组,元组的第一个元素为x(1),第二个元素为一个元组,元组的第一个元素为x(2),第二个元素为1
  .map(x=>(x._1,(x._2,1)))
  // 按照x(1)进行分组,并对每个分组中的元组进行reduce操作,将x(2)相加,将1相加
  .reduceByKey((x,y)=>(x._1+y._1, x._2+y._2))
  // 将每个元组映射为一个元组,元组的第一个元素为x(1),第二个元素为x(2)除以1
  .map(x=>(x._1, x._2._1/x._2._2))

 将rdd转换成DataFrame

//用Row和schema信息组成Dataframe
//通过定义schema,可以确保数据的结构一致性,便于后续的数据分析和处理。
val log_schema: StructType = StructType(
  Array(
    StructField("event_time", StringType), // 事件发生时间
    StructField("url", StringType), // 请求的url
    StructField("method", StringType), // 请求方法
    StructField("status", StringType), // 响应状态码
    StructField("sip", StringType), // 客户端ip
    StructField("user_uip", StringType), // 用户ip
    StructField("action_prepend", StringType), // 操作前缀
    StructField("action_client", StringType) // 客户端操作
  )
)
//通过row,schema信息组成dataframe
import spark.implicits._                     //要使用dataframe和dataset需要该类
val logDF: DataFrame = spark.createDataFrame(rowRdd, log_schema)// 创建一个名为logDF的DataFrame,其数据来源于rowRdd和log_schema
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值