Spark加载CSV和JSON文件(附在虚拟机中执行jar包)

加载CSV文件

数据样例

user_id,locale,birthyear,gender,joinedAt,location,timezone
3197468391,id_ID,1993,male,2012-10-02T06:40:55.524Z,Medan Indonesia,480
3537982273,id_ID,1992,male,2012-09-29T18:03:12.111Z,Medan Indonesia,420
823183725,en_US,1975,male,2012-10-06T03:14:07.149Z,Stratford Ontario,-240
1872223848,en_US,1991,female,2012-11-04T08:59:43.783Z,Tehran Iran,210
3429017717,id_ID,1995,female,2012-09-10T16:06:53.132Z,420
627175141,ka_GE,1973,female,2012-11-01T09:59:17.590Z,Tbilisi Georgia,240
2752000443,id_ID,1994,male,2012-10-03T05:22:17.637Z,Medan Indonesia,420

使用SparkContext装载CSV数据源

方法一:mapPartitionsWithIndex

val file1 = sc.textFile("data/users.csv")
    val fields1 = file1.mapPartitionsWithIndex((index, value) => {
      if (index == 0) value.drop(1)
      else value
    }).map(x => x.split(","))
    println("fields1:"+fields1.count())

这种是使用mapPartitionsWithIndex方法,index是行的下标,value就是每行的值,如果行下标为0,即为首行各列列名,那么就删除掉第一行,剩下的即为内容。但有时一个文件中可能不仅包含一行的列名,此时用这种方法只能删除第一行,如再删除其他标题还需另确定行数,所以建议视情况而使用。
方法二:filter

val fields2 = file1.filter(value=>value.startsWith("user_id")==false).map(x=>x.split(","))
   println(fields2.count())
   fields2.foreach(x=>println(x.mkString(",")))

用filter进行过滤,过滤出起始元素不是“user_id”的行。这个方法的好处就是能根据我们自身的要求,去除列名,定位更加准确。

使用SparkSession装载CSV数据源

 val conf=new SparkConf().setMaster("local[2]").setAppName("csv")
  val spark = SparkSession.builder().config(conf).getOrCreate()
    val dataFrame = spark.read.format("csv").option("header","true").load("data/users.csv")
    dataFrame.printSchema() //打印表的属性
    dataFrame.select("user_id","locale").show(5)

在这里插入图片描述

format中输入的是文件类型,option表示是否显示每列的列名。true为文件自带列名,如上图所示。如果为false则为系统默认。我们也可以使用select来展示我们所需要的内容,类似于SQL中的select。show表示显示的行数,默认为20行。
如果option中改为false,则结果为:

val dataFrame2 = spark.read.format("csv").option("header","false").load("data/users.csv")
    dataFrame2.printSchema()
    dataFrame2.select("_c0","_c1").show()

在这里插入图片描述
默认的列名为_c0,_c1等等,同时列名作为内容的一部分。

文件的修改

重命名

在工作中,我们所得到的文件并不一定全是有列名的,有可能只要数据,当我们加载完数据后,每列只有默认的列名:_c0,_c1,_c2,此时就需要我们给它们重命名。
以上面的数据为例。dataFrame2加载的数据是没有列名的。
使用withColumnRenamed

val dataFrame3 = dataFrame2.withColumnRenamed("_c0","user_id")
    dataFrame2.printSchema()
    println("========================")
    dataFrame3.printSchema()

withColumnRenamed生成的是一个新的dataFrame。_c0是就列名,user_id是新列名。
在这里插入图片描述

修改数据类型

我们以第一列为例,第一列的数据类型为string类型,我们这里把它修改为Long类型。

val frame = dataFrame3.withColumn("user_id",dataFrame3.col("user_id").cast("Long"))
    frame.printSchema()

在这里插入图片描述
如果withColumn中的前后列名不同,那么就会新增一个新的列。

val frame2 = dataFrame3.withColumn("id",dataFrame3.col("user_id").cast("Long"))
    frame2.printSchema()
    frame2.show()

在这里插入图片描述

删除列

使用drop删除。

val frame2 = dataFrame3.withColumn("id",dataFrame3.col("user_id").cast("Long"))
 val frame3 = frame2.drop("id")
    frame3.printSchema()
    frame3.show(5)

这里删除了id列。
在这里插入图片描述

加载JSON数据源

数据

{“name”:“Michael”}
{“name”:“Andy”,“Age”:30}
{“name”:“Justin”,“Age”:19}

SparkContext加载加载JSON

scala.util.parsing.json._
val lines = sc.textFile("data/users.json")
      val line = lines.map(x=>JSON.parseFull(x))
    line.foreach(println)

在这里插入图片描述
再加载json文件前,需要先导入json包:scala.util.parsing.json._。输出结果为Map类型。

SparkSession加载JSON

方法和前面加载csv格式一样

val conf=new SparkConf().setMaster("local[2]").setAppName("json")
    val sc = new SparkContext(conf)
    val spark=SparkSession.builder().config(conf).getOrCreate()
    val frame = spark.read.format("json").load("data/users.json")
    frame.printSchema()
    frame.show()

在这里插入图片描述
对Age重命名:

val frame2 = frame.withColumnRenamed("Age","age")
    frame2.show()

在这里插入图片描述
值得一提的是,在前面我们说过,使用withColumn重设数据类型的时候,如果改变列名,会新增一列修改的列,但是,如果我们只改变其大小写,则不会新增一列,只会修改列名:

val fram3=frame.withColumn("age",frame.col("Age").cast("String"))
    fram3.show()

在这里插入图片描述

加载Jar包

以单词统计为例。
从hdfs上读取文件,进行统计
为了方便以后的调用,在虚拟中创建一个properties文件,文件内容为读取文件的路径,以及写入文件的路径。我们直接从文件中读取相关的路径,在后续的开发工作中,只需要修改下文件中的路径,就可以从不同的路径对文件进行读写。这里我以hdfs路径为列:

loadpath:hdfs://192.168.136.30:9000/data/File/words.txt
outpath:hdfs://192.168.136.30:9000/data/wordCount

需求实现步骤:
idea端:

  1. 创建properties文件;
  2. 创建properties对象;
  3. 得到读取和写入文件路径;
  4. 加载目标文件;
  5. 单词统计;
  6. 写入路径;
  7. 运行结束后停止sc;
  8. 打jar包发送到虚拟机;
val conf=new SparkConf().setMaster("local[2]").setAppName("wordCount")
    val sc = new SparkContext(conf)
//创建properties对象
    val pro = new Properties()
    //加载properties文件路径
    pro.load(new FileInputStream("/data/path.properties"))
    //得到读取和写入文件路径
    val loadFilePath = pro.get("loadpath").toString
    val outFilePath = pro.get("outpath").toString
  //加载目标文件
    val lines = sc.textFile(loadFilePath)
    //单词统计
    val count = lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
    //写入路径
    count.saveAsTextFile(outFilePath)
    //运行结束后停止sc
    sc.stop()

在这里插入图片描述
选择相应scala文件
在这里插入图片描述完成后确定:
在这里插入图片描述
在这里插入图片描述
点击build创建jar包:
在这里插入图片描述
创建完成的jar包在out目录下:
在这里插入图片描述
把jar包上传到虚拟机中。
虚拟机端

  1. 启动hadoop和spark(两个start-all.sh);
  2. 删除jar包中的DSA和SF文件;
  3. shell指令,实现需求。
//启hadoop
start-all.sh
//启动spark服务
sbin/start-all.sh

启动后有如下进程:
在这里插入图片描述
删除文件:
我们用解压器打开我们打好的jar包,把META-INF/DUMMY.DSA文件和META-INF/DUMMY.SF两个文件删除,这两个相当于是jar包中的一个安全或加密文件。在这里插入图片描述
如果不删除,在我们执行代码的时候会报错,例如:
在这里插入图片描述
spark submit代码实现:

spark-submit --class Test1.demo --master local[2] ./SparkRDDExercise.jar

补充:spark submit的参数
在这里插入图片描述
代码运行完后查看上传信息:因为设置了两个分区,所以有两个文件,我们可以通过cat查看文件内容。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值