大数据培训Spark框架:RDD、DataFrame的区别

RDD、DataFrame是什么

在Spark中,RDD、DataFrame是最常用的数据类型。

什么是RDD?

RDD(Resilient Distributed Datasets)提供了一种高度受限的共享内存模型。

即RDD是只读的记录分区的集合,只能通过在其他RDD执行确定的转换操作(如map、join和group by)而创建,然而这些限制使得实现容错的开销很低。

RDD仍然足以表示很多类型的计算,包括MapReduce和专用的迭代编程模型(如Pregel)等。

什么是DataFrame?

DataFrame是一种分布式的数据集,并且以列的方式组合的。大数据培训类似于关系型数据库中的表。可以说是一个具有良好优化技术的关系表。

DataFrame背后的思想是允许处理大量结构化数据。提供了一些抽象的操作,如select、filter、aggregation、plot。

DataFrame包含带schema的行。schema是数据结构的说明。相当于具有schema的RDD。

RDD、DataFrame有什么特性

在Apache Spark 里面DF 优于RDD,但也包含了RDD的特性。

RDD和DataFrame的共同特征是不可性、内存运行、弹性、分布式计算能力。

它允许用户将结构强加到分布式数据集合上。因此提供了更高层次的抽象。

我们可以从不同的数据源构建DataFrame。例如结构化数据文件、Hive中的表、外部数据库或现有的RDDs。

DataFrame的应用程序编程接口(api)可以在各种语言中使用,包括Python、Scala、Java和R。

RDD的五大特性:

1.(必须的)可分区的: 每一个分区对应就是一个Task线程。

2.(必须的)计算函数(对每个分区进行计算操作)。

3.(必须的)存在依赖关系。

4.(可选的)对于key-value数据存在分区计算函数。

5.(可选的)移动数据不如移动计算(将计算程序运行在离数据越近越好)。

DataFrame的特性:

1.支持从KB到PB级的数据量。

2.支持多种数据格式和多种存储系统。

3.通过Catalyst优化器进行先进的优化生成代码。

4.通过Spark无缝集成主流大数据工具与基础设施。

5.API支持Python、Java、Scala和R语言。

两者的区别

RDD是弹性分布式数据集,数据集的概念比较强一点;RDD容器可以装任意类型的可序列化元素(支持泛型)。

RDD的缺点是无从知道每个元素的【内部字段】信息。意思是下图不知道Person对象的姓名、年龄等。

 

DataFrame也是弹性分布式数据集,但是本质上是一个分布式数据表,因此称为分布式表更准确。DataFrame每个元素不是泛型对象,而是Row对象。

DataFrame的缺点是Spark SQL DataFrame API 不支持编译时类型安全,因此,如果结构未知,则不能操作数据;同时,一旦将域对象转换为Data frame ,则域对象不能重构。

DataFrame=RDD-【泛型】+schema+方便的SQL操作+【catalyst】优化

 

DataFrame优于RDD,因为它提供了内存管理和优化的执行计划。总结为以下两点:

a.自定义内存管理:当数据以二进制格式存储在堆外内存时,会节省大量内存。除此之外,没有垃圾回收(GC)开销。还避免了昂贵的Java序列化。因为数据是以二进制格式存储的,并且内存的schema是已知的。
b.优化执行计划:这也称为查询优化器。可以为查询的执行创建一个优化的执行计划。优化执行计划完成后最终将在RDD上运行执行。

两者之间的转换

RDD可以转换为DataFrame

(1).通过RDD[Row]转换为DF

核心步骤:

1.定义RDD,每个元素都是Row类型

2.将上面的RDD[Row]转换为DataFrame,df=spark.createDataFrame(row_rdd)

代码:

# -*- coding:utf-8 -*-

# Desc:This is Code Desc

from pyspark import Row

from pyspark.sql import SparkSession

import os

os.environ['SPARK_HOME'] = '/export/server/spark'

PYSPARK_PYTHON = "/root/anaconda3/bin/python"

# 当存在多个版本时,不指定很可能会导致出错

os.environ["PYSPARK_PYTHON"] = PYSPARK_PYTHON

os.environ["PYSPARK_DRIVER_PYTHON"] = PYSPARK_PYTHON

if __name__ == '__main__':

#1-创建上下文对象

spark=SparkSession.builder.appName('test').master('local[*]').getOrCreate()

sc=spark.sparkContext

sc.setLogLevel('WARN')

#2-加载文本文件,形成RDD

rdd1=sc.textFile('file:///export/pyworkspace/pyspark_sz27/pyspark_sql/data/sql/people.txt')

for x in rdd1.collect():print(x)

#3-将RDD的每个元素从string转成Row

rdd2=rdd1.map(lambda str: Row(name=str.split(',')[0], age=int(str.split(',')[1].strip()) ) )

#4-调用spark.createDataFrame(RDD[Row]),得到DataFrame

df=spark.createDataFrame(rdd2)

#5-打印df的schema信息

df.printSchema()

#6-打印df的行数据

df.show()

#7-关闭退出

spark.stop()

(2).RDD[元组或列表]+自定义Schema信息

核心步骤:

1.RDD的每个元素转换为元组

2.依据元组的值自定义schema

3.Spark.createDataFrame(rdd,schema)

代码:

# -*- coding:utf-8 -*-

# Desc:This is Code Desc

from pyspark import Row

from pyspark.sql import SparkSession

import os

from pyspark.sql.types import StructType, StructField, StringType, IntegerType

os.environ['SPARK_HOME'] = '/export/server/spark'

PYSPARK_PYTHON = "/root/anaconda3/bin/python"

# 当存在多个版本时,不指定很可能会导致出错

os.environ["PYSPARK_PYTHON"] = PYSPARK_PYTHON

os.environ["PYSPARK_DRIVER_PYTHON"] = PYSPARK_PYTHON

if __name__ == '__main__':

#1-创建上下文对象

spark=SparkSession.builder.appName('test').master('local[*]').getOrCreate()

sc=spark.sparkContext

sc.setLogLevel('WARN')

#2-加载文本文件,形成RDD

rdd1=sc.textFile('file:///export/pyworkspace/pyspark_sz27/pyspark_sql/data/sql/people.txt')

#3-将RDD的每个元素从string转成 Tuple

rdd2=rdd1.map(lambda str:(str.split(',')[0], int(str.split(',')[1].strip())))

#4-为上述tuple量身定义schema

schema=StructType( [

StructField('name',StringType()),

StructField('age',IntegerType())

])

#5-调用spark.createDataFrame(RDD[Tuple],schema),得到DataFrame

df=spark.createDataFrame(rdd2,schema)

#6-打印df的schema信息

df.printSchema()

#7-打印df的行数据

df.show()

#8-关闭退出

spark.stop()

(3).RDD[集合]+toDF(指定列名)

核心步骤:

1.RDD的每行转换为元组或列表

2.再加上toDF(指定多个列名)

代码:

# -*- coding:utf-8 -*-

# Desc:This is Code Desc

from pyspark import Row

from pyspark.sql import SparkSession

import os

from pyspark.sql.types import StructType, StructField, StringType, IntegerType

os.environ['SPARK_HOME'] = '/export/server/spark'

PYSPARK_PYTHON = "/root/anaconda3/bin/python"

# 当存在多个版本时,不指定很可能会导致出错

os.environ["PYSPARK_PYTHON"] = PYSPARK_PYTHON

os.environ["PYSPARK_DRIVER_PYTHON"] = PYSPARK_PYTHON

if __name__ == '__main__':

#1-创建上下文对象

spark=SparkSession.builder.appName('test').master('local[*]').getOrCreate()

sc=spark.sparkContext

sc.setLogLevel('WARN')

#2-加载文本文件,形成RDD

rdd1=sc.textFile('file:///export/pyworkspace/pyspark_sz27/pyspark_sql/data/sql/people.txt')

#3-将RDD的每个元素从string转成 Tuple

rdd2=rdd1.map(lambda str:(str.split(',')[0], int(str.split(',')[1].strip())))

#4-调用toDF传输字段名称

df=rdd2.toDF(['name','age'])

#5-打印df的schema信息

df.printSchema()

#6-打印df的行数据

df.show()

#7-关闭退出

spark.stop()

综上,DataFrame API能够提高spark的性能和扩展性。避免了构造每行在dataset中的对象,造成GC的代价。不同于RDD API,能构建关系型查询计划。更加有有利于熟悉执行计划的开发人员,同理不一定适用于所有人。

文章来源于数据说话

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值