推广

大数据开发:Spark框架Dataset API

iseeyu2年前 (2024-02-21)推广138

从概念上讲,我们可以将Scala中的DataFrame视为通用对象集合Dataset[Row]的别名,其中Row是通用非类型JVM对象,可能包含不同类型的字段。相比之下,Dataset是Scala中或Java中的强类型JVM对象的集合。或者,如Dataset文档所说,Dataset是:

特定域对象的强类型集合,可以使用函数或关系操作进行转换。Scala中的每个Dataset都有一个称为DataFrame的无类型视图,它是一个Dataset Row。

1、有类型的对象、非类型的对象和通用行

在Spark支持的语言中,数据集只在Java和Scala中有意义,而在Python和R中,只有DataFrame有意义。这是因为Python和R不是编译时类型安全的;类型是在执行期间动态推断或分配的,而不是在编译时动态分配的。在Scala和Java中,情况正好相反:类型在编译时绑定到变量和对象。然而,在Scala中,DataFrame只是非类型Dataset[Row]的别名。

Row是Spark中的通用对象类型,它包含可以使用索引访的混合类型的集合。在内部,Spark会操作Row对象,并将它们转换为相应的等效类型。例如,对于Scala或Java和Python,Row中的一个整数字段将分别映射或转换为整数类型:

// In Scala

import org.apache.spark.sql.Row

val row = Row(350, true, “Learning Spark 2E”, null)

# In Python

from pyspark.sql import Row

row = Row(350, True, “Learning Spark 2E”, None)

使用行对象的索引,可以使用公共getter方法访问各个字段:

// In Scala

row.getInt(0)

res23: Int = 350

row.getBoolean(1)

res24: Boolean = true

row.getString(2)

res25: String = Learning Spark 2E

# In Python

row[0]

Out[13]: 350

row[1]

Out[14]: True

row[2]

Out[15]: ‘Learning Spark 2E’

相比之下,类型化对象是JVM中实际的Java或Scala类对象。数据集中的每个元素都映射到一个JVM对象。

2、创建DataSet

与从数据源创建DataFrame一样,在创建数据集时,你必须知道schema。换句话说,你需要了解数据类型。尽管使用JSON和CSV数据可以推断出schema,但对于大型数据集,这是资源密集型的(成本昂贵),非常消耗资源。

在Scala中创建数据集时,为结果数据集指定schema最简单的方法是使用样例类(Case classes)。在Java中,使用JavaBean类(我们在第6章中进一步讨论JavaBean和Scala样例类)。

Scala: 样例类(Case classes)

当你希望将自己的域中特定的对象实例化为数据集时,你可以通过在Scala中定义一个样例类来实例化。作为一个例子,让我们查看JSON文件中从物联网设备读取的集合。

我们的文件有几行JSON字符串,外观如下:

{“device_id”: 198164, “device_name”: “sensor-pad-198164owomcJZ”, “ip”:

“80.55.20.25”, “cca2”: “PL”, “cca3”: “POL”, “cn”: “Poland”, “latitude”:

53.080000, “longitude”: 18.620000, “scale”: “Celsius”, “temp”: 21,

“humidity”: 65, “battery_level”: 8, “c02_level”: 1408,”lcd”: “red”,

“timestamp” :1458081226051}

要将每个JSON条目表示为DeviceIoTData,一种特定领域的对象,我们可以定义一个Scala样例类:

case class DeviceIoTData (battery_level: Long, c02_level: Long,

cca2: String, cca3: String, cn: String, device_id: Long,

device_name: String, humidity: Long, ip: String, latitude: Double,

lcd: String, longitude: Double, scale:String, temp: Long,

timestamp: Long)

一旦定义,我们可以使用它读取文件并将返回的内容Dataset[Row]转换为Dataset[DeviceIoTData](输出被截断以适合页面):

// In Scala

val ds = spark.read

.json(“/databricks-datasets/learning-spark-v2/iot-devices/iot_devices.json”)

.as[DeviceIoTData]

ds: org.apache.spark.sql.Dataset[DeviceIoTData] = [battery_level…]

ds.show(5, false)

+————-|———|—-|—-|————-|———|—+

|battery_level|c02_level|cca2|cca3|cn |device_id|…|

+————-|———|—-|—-|————-|———|—+

|8 |868 |US |USA |United States|1 |…|

|7 |1473 |NO |NOR |Norway |2 |…|

|2 |1556 |IT |ITA |Italy |3 |…|

|6 |1080 |US |USA |United States|4 |…|

|4 |931 |PH |PHL |Philippines |5 |…|

+————-|———|—-|—-|————-|———|—+

only showing top 5 rows

3、Dataset操作

就像你可以在DataFrame上执行转换和操作一样,你也可以使用数据集。根据操作类型的不同,操作结果将会有所不同:

// In Scala

val filterTempDS = ds.filter({d => {d.temp > 30 && d.humidity > 70})

filterTempDS: org.apache.spark.sql.Dataset[DeviceIoTData] = [battery_level…]

filterTempDS.show(5, false)

+————-|———|—-|—-|————-|———|—+

|battery_level|c02_level|cca2|cca3|cn |device_id|…|

+————-|———|—-|—-|————-|———|—+

|0 |1466 |US |USA |United States|17 |…|

|9 |986 |FR |FRA |France |48 |…|

|8 |1436 |US |USA |United States|54 |…|

|4 |1090 |US |USA |United States|63 |…|

|4 |1072 |PH |PHL |Philippines |81 |…|

+————-|———|—-|—-|————-|———|—+

only showing top 5 rows

在此查询中,我们使用一个函数作为数据集方法filter()的参数。这是一个具有很多签名的重载方法。我们使用的版本采用filter(func: (T) > Boolean): Dataset[T] lambda函数func: (T) > Boolean作为参数。

lambda函数的参数是类型为DeviceIoTData的JVM对象。这样,我们可以使用点(.)表示法访问其各个数据字段,就像在Scala类或JavaBean中一样。

另一件需要注意的事情是,对于DataFrame,你将filter()条件表示为类似SQL的DSL操作,这些操作是与语言无关的。对于数据集,我们利用原生语言的表达式作为Scala或Java代码。

总的来说,我们可以在数据集上执行filter(),map(),groupBy(),select(),take()这些操作,与DataFrame上的操作相似。在某种程度上,数据集与RDD相似,因为它们提供了与上述方法类似的接口以及编译时安全性,但具有更容易读取和面向对象的编程接口。

当我们使用数据集时,底层的Spark SQL引擎会处理JVM对象的创建、控制版本、序列化和反序列化。它还借助数据集编码器来处理Java外堆内存管理。

关于大数据开发学习,Spark框架Dataset API,以上就为大家做了简单的介绍了。Spark在大数据学习当中,是非常重要的一块,而API编程,是必须要掌握的重要基础,建议多家练习。

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://0291.com.cn/post/57068.html

相关文章

刚接触SEO的菜鸟如何优化博客类网站。

刚接触SEO的菜鸟如何优化博客类网站。

很多朋友做好博客后,想要提高排名就要做博客站内优化,但是不知道怎样做好站内的优化工作,那么博客是怎么去做营销优化呢,其实方法很多,所以在做优化的过程中我来跟大家分享一些经验。 博客标题修改 博客内容主要是对网络营销方法,所以博客标题可以正式指定为:互联网营销博客。小编会研究各种网络营销...

如何学习seo。

如何学习seo。

最近看到有人问:如何学习seo,其实学习seo不难,只要下定决心要学习seo ,就要制定一份详细的学习计划,先把基础知识学扎实,然后用wordpress建立一个博客,边学习边实践,这是最好的学习方法. 学会基本的seo基础知识,可以找到一份seo专员的职位,可以在边工作的时候边学习,工作中遇...

向上生长 | 如何跨越阶层和积累财富?

向上生长 | 如何跨越阶层和积累财富?

如何向上跨越阶层?社会上绝大部分人没有努力过,没有主动过,只是被动接受的摆布。“努力”是对生活主动出击,克服恐惧,迎接挑战;被动地被生活蹂躏,只能叫“辛苦”。努力,首先要承认自己没有天赋,承认自己的平庸,肯下笨功夫。要平心静气地去慢启动,不要贪多求快。注重量的积...

能量与信息是什么关系

我:将手机的备份文件夹里,存有一年多的视频和照片,导入到电脑里。回看干过的各种杂事,去过的地方,吃喝玩乐的轨迹,突然产生了一种幻灭感,也深深感受到人作为一个能量信息体,具有的奇特性。幻灭感是各种事情,如果没有这些影像记录,可能永远不会再记起,我们经历过的人和事,有些是永远不...

逆向思维:真正赚钱厉害的高手,都是靠无懈可击的正道阳谋

逆向:真正厉害的高手,都是靠无懈可击的正道阳谋。世界上有一条最基本的核心原理,那就是简单!任何事情都是,越简单越有效,越简单越容易,越简单就越容易出结果。学习就是死记硬背,没有任何窍门,漏洞可钻。锻炼最好的方式,就是跑步,走路,比任何健身器械锻炼的效果都好。赚钱这件事情也一...

Unity Shader 极简实践5——2D图片描边

Unity Shader 极简实践5——2D图片描边

《赛博朋克》朱迪·阿尔瓦雷兹 这篇文章描述如何对2D图片(Unity 中的 Sprite 和 UGUI Image) 做描边 1. 内描边 思路:在片元着色器中,判断当前片元的上下左右像素(使用数值width来确定上下左右“多远”,从而得到描边的宽度),上下左右四个像素的 alpha...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片