Spark入门梳理3-Spark数据结构

文章目录

  • Spark编程基础-搭配Jupyter
    • 1.1 Spark SQL简介
      • 1.1.1 Spark SQL架构
    • 1.2 DataFrame与RDD的区别
    • 1.3 DataFrame的创建
    • 1.4 从RDD转换得到DataFrame
      • 1.4.1 利用反射机推断RDD模式

Spark编程基础-搭配Jupyter

1.1 Spark SQL简介

Spark 即 Hive on Spark。它的前身是Shark。
Shark的设计有两方面缺陷:

  1. 执行优化完全依赖于Hive,不方便添加新的优化策略
  2. Shark是线程级并行,而MapReduce是进程级并行。
    因此,Shark在兼容Hive的实现上存在线程安全的问题,导致Shark不得不使用另外一套独立维护的打了补丁的Hive源码分支
    在2014年,因为Shark实现继承大量Hive代码的原因,特别是基于MapReduce设计的部分导致成为整个项目的瓶颈,Shark项目终止,并转向Spark SQL的开发。

1.1.1 Spark SQL架构

Spark SQL增加了SchemaRDD(即带有Schema信息的RDD),使用户数据可以来自RDD、Hive、HDFS、Cassandra等外部数据,也可以是json格式数据。从Spark1.2 升级到Spark1.3以后,Spark SQL中的SchemaRDD变为了DataFrame,DataFrame相对于SchemaRDD有了较大改变,同时提供了更多好用且方便的API,如图所示。
Spark入门梳理3-Spark数据结构_第1张图片

1.2 DataFrame与RDD的区别

首先我们看一下下图,这里是RDD与DataFrame的区别,熟悉python pandas的就知道,在数据处理中,pandas在处理大数据的时候有绝对的话事权,支持各种数据结构的存储,可以清楚知道哪些列名,名称和类型;
而RDD是分布式中Java对象的集合,可以理解为做了一层封装,也就是RDD中对象的属性对于使用者是隐蔽的,这不同于DataFrame可以清晰的了解到详细的结构信息。
Spark入门梳理3-Spark数据结构_第2张图片

1.3 DataFrame的创建

在Linux中打开“终端”,进入Shell命令提示符状态。
在Spark中为我们提供了几个样例数据,就保存在
“/你的spark目录/spark/examples/src/main/resources/”,这个目录下有两个样例数据:
people.json 和 people.txt
people.json内容如下:

{"name":"Michael"}
{"name":"Andy", "age":30}
{"name":"Justin", "age":19}

people.txt文件的内容如下:

Michael, 29
Andy, 30
Justin, 19
  • 打开pyspark:
  • 进入spark目录:
  • ./bin/pyspark
  • 之后这里就是python的环境,运行以下代码:
>>> spark=SparkSession.builder.getOrCreate()
>>> df = spark.read.json("file:///usr/local/spark/examples/src/main/resources/people.json")
>>> df.show()
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

之后的处理可以参考一下pandas官网和pyspark中的使用,这里有一个 sparkDataFrame与Pandas中DataFrame的区别,可以帮助大家在python中更熟练的使用
Spark与Pandas中DataFrame对比(详细)

1.4 从RDD转换得到DataFrame

Spark官网提供了两种方法来实现从RDD转换得到DataFrame,第一种方法是,利用反射来推断包含特定类型对象的RDD的schema,适用对已知数据结构的RDD转换;第二种方法是,使用编程接口,构造一个schema并将其应用在已知的RDD上。
这里只使用第一种方法,对于第二种方法并不适用于喜欢python的

1.4.1 利用反射机推断RDD模式

>>> from pyspark.sql.types import Row
>>> def f(x):
...     rel = {}
...     rel['name'] = x[0]
...     rel['age'] = x[1]
...     return rel
... 
>>> peopleDF = sc.textFile("file:///usr/local/spark/examples/src/main/resources/people.txt").map(lambda line : line.split(',').map(lambda x: Row(**f(x))).toDF()
>>> peopleDF.createOrReplaceTempView("people")  //必须注册为临时表才能供下面的查询使用
 
>>> personsDF = spark.sql("select * from people")
>>> personsDF.rdd.map(lambda t : "Name:"+t[0]+","+"Age:"+t[1]).foreach(print)
 
Name: 19,Age:Justin
Name: 29,Age:Michael
Name: 30,Age:Andy

line.split(',').map(lambda x: Row(**f(x))).toDF()
这里就是正宗的python写法,按字符串分割之后通过map函数进行映射,而lambda 就是python中的匿名函数,toDF()是pyspark中的方法,具体可以参考官网,而**F(x)则是将字典映射的写法
对于spark与python还有很多需要学习的地方,因为目前使用场景几乎没有,所以先留个笔记,之后在仔细补齐。

你可能感兴趣的:(机器学习)