初识spark,需要对其API有熟悉的了解才能方便开发上层应用。本文用图形的方式直观表达相关API的工作特点,并提供了解新的API接口使用的方法。例子代码全部使用python实现。

1. 数据源准备

准备输入文件:

$ cat /tmp/in
apple
bag bag
cat cat cat

启动pyspark:

$ ./spark/bin/pyspark

使用textFile创建RDD:

>>> txt = sc.textFile("file:///tmp/in", 2)

查看RDD分区与数据:

>>> txt.glom().collect()
[[u'apple', u'bag bag'], [u'cat cat cat']]

2. transformation

flatMap

处理RDD的每一行,一对多映射。

代码示例:

>>> txt.flatMap(lambda line: line.split()).collect()
[u'apple', u'bag', u'bag', u'cat', u'cat', u'cat']

示意图:

map

处理RDD的每一行,一对一映射。

代码示例:

>>> txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).collect()
[(u'apple', 1), (u'bag', 1), (u'bag', 1), (u'cat', 1), (u'cat', 1), (u'cat', 1)]

示意图:

filter

处理RDD的每一行,过滤掉不满足条件的行。

代码示例:

>>> txt.flatMap(lambda line: line.split()).filter(lambda word: word !='bag').collect()
[u'apple', u'cat', u'cat', u'cat']

示意图:

mapPartitions

逐个处理每一个partition,使用迭代器it访问每个partition的行。

代码示例:

>>> txt.flatMap(lambda line: line.split()).mapPartitions(lambda it: [len(list(it))]).collect()
[3, 3]

示意图:

mapPartitionsWithIndex

逐个处理每一个partition,使用迭代器it访问每个partition的行,index保存partition的索引,等价于mapPartitionsWithSplit(过期函数)。

代码示例:

>>> txt.flatMap(lambda line: line.split()).mapPartitionsWithIndex(lambda index, it: [index]).collect()
[0, 1]

示意图:

sample

根据采样因子指定的比例,对数据进行采样,可以选择是否用随机数进行替换,seed用于指定随机数生成器种子。第一个参数表示是否放回抽样,第二个参数表示抽样比例,第三个参数表示随机数seed。

代码示例:

>>> txt.flatMap(lambda line: line.split()).sample(False, 0.5, 5).collect()
[u'bag', u'bag', u'cat', u'cat']

示意图:

union

合并RDD,不去重。

代码示例:

>>> txt.union(txt).collect()
[u'apple', u'bag bag', u'cat cat cat', u'apple', u'bag bag', u'cat cat cat']

示意图:

distinct

对RDD去重。

代码示例:

>>> txt.flatMap(lambda line: line.split()).distinct().collect()
[u'bag', u'apple', u'cat']

示意图:

groupByKey

在一个(K,V)对的数据集上调用,返回一个(K,Seq[V])对的数据集。

代码示例:

>>> txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).groupByKey().collect()
[(u'bag', <pyspark.resultiterable.ResultIterable object at 0x128a150>), (u'apple', <pyspark.resultiterable.ResultIterable object at 0x128a550>), (u'cat', <pyspark.resultiterable.ResultIterable object at 0x13234d0>)]
>>> txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).groupByKey().collect()[0][1].data
[1, 1]

示意图:

reduceByKey

在一个(K,V)对的数据集上调用时,返回一个(K,V)对的数据集,使用指定的reduce函数,将相同key的值聚合到一起。

代码示例:

>>> txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b).collect()
[(u'bag', 2), (u'apple', 1), (u'cat', 3)]

示意图:

aggregateByKey

自定义聚合函数,类似groupByKey。在一个(K,V)对的数据集上调用,不过可以返回一个(K,Seq[U])对的数据集。

代码示例(实现groupByKey的功能):

>>> txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).aggregateByKey([], lambda seq, elem: seq + [elem], lambda a, b: a + b).collect()
[(u'bag', [1, 1]), (u'apple', [1]), (u'cat', [1, 1, 1])]

sortByKey

在一个(K,V)对的数据集上调用,K必须实现Ordered接口,返回一个按照Key进行排序的(K,V)对数据集。升序或降序由ascending布尔参数决定。

代码示例:

>>> txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b).sortByKey().collect()
[(u'apple', 1), (u'bag', 2), (u'cat', 3)]

示意图:

join

在类型为(K,V)和(K,W)类型的数据集上调用时,返回一个相同key对应的所有元素对在一起的(K, (V, W))数据集。

代码示例:

>>> sorted_txt = txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b).sortByKey()
>>> sorted_txt.join(sorted_txt).collect()
[(u'bag', (2, 2)), (u'apple', (1, 1)), (u'cat', (3, 3))]

示意图:

cogroup

在类型为(K,V)和(K,W)的数据集上调用,返回一个 (K, (Seq[V], Seq[W]))元组的数据集。这个操作也可以称之为groupwith。

代码示例:

>>> sorted_txt = txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b).sortByKey()
>>> sorted_txt.cogroup(sorted_txt).collect()
[(u'bag', (<pyspark.resultiterable.ResultIterable object at 0x1323790>, <pyspark.resultiterable.ResultIterable object at 0x1323310>)), (u'apple', (<pyspark.resultiterable.ResultIterable object at 0x1323990>, <pyspark.resultiterable.ResultIterable object at 0x1323ad0>)), (u'cat', (<pyspark.resultiterable.ResultIterable object at 0x1323110>, <pyspark.resultiterable.ResultIterable object at 0x13230d0>))]
>>> sorted_txt.cogroup(sorted_txt).collect()[0][1][0].data
[2]

示意图:

cartesian

笛卡尔积,在类型为 T 和 U 类型的数据集上调用时,返回一个 (T, U)对数据集(两两的元素对)。

代码示例:

>>> sorted_txt = txt.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b).sortByKey()
>>> sorted_txt.cogroup(sorted_txt).collect()
[(u'bag', (<pyspark.resultiterable.ResultIterable object at 0x1323790>, <pyspark.resultiterable.ResultIterable object at 0x1323310>)), (u'apple', (<pyspark.resultiterable.ResultIterable object at 0x1323990>, <pyspark.resultiterable.ResultIterable object at 0x1323ad0>)), (u'cat', (<pyspark.resultiterable.ResultIterable object at 0x1323110>, <pyspark.resultiterable.ResultIterable object at 0x13230d0>))]
>>> sorted_txt.cogroup(sorted_txt).collect()[0][1][0].data
[2]

示意图:

pipe

处理RDD的每一行作为shell命令输入,shell命令结果为输出。

代码示例:

>>> txt.pipe("awk '{print $1}'").collect()
[u'apple', u'bag', u'cat']

示意图:

coalesce

减少RDD分区数。

代码示例:

>>> txt.coalesce(1).collect()
[u'apple', u'bag bag', u'cat cat cat']

示意图:

repartition

对RDD重新分区,类似于coalesce。

代码示例:

>>> txt.repartition(1).collect()
[u'apple', u'bag bag', u'cat cat cat']

zip

合并两个RDD序列为元组,要求序列长度相等。

代码示例:

>>> txt.zip(txt).collect()
[(u'apple', u'apple'), (u'bag bag', u'bag bag'), (u'cat cat cat', u'cat cat cat')]

示意图:

3. action

reduce

聚集数据集中的所有元素。

代码示例:

>>> txt.reduce(lambda a, b: a + " " + b)
u'apple bag bag cat cat cat'

示意图:

collect

以数组的形式,返回数据集的所有元素。

代码示例:

>>> txt.collect()
[u'apple', u'bag bag', u'cat cat cat']

count

返回数据集的元素的个数。

代码示例:

>>> txt.count()
3

first

返回数据集第一个元素。

代码示例:

>>> txt.first()
u'apple'

take

返回数据集前n个元素。

代码示例:

>>> txt.take(2)
[u'apple', u'bag bag']

takeSample

采样返回数据集前n个元素。第一个参数表示是否放回抽样,第二个参数表示抽样个数,第三个参数表示随机数seed。

代码示例:

>>> txt.takeSample(False, 2, 1)
[u'cat cat cat', u'bag bag']

takeOrdered

排序返回前n个元素。

代码示例:

>>> txt.takeOrdered(2)
[u'apple', u'bag bag']

saveAsTextFile

将数据集的元素,以textfile的形式,保存到本地文件系统,HDFS或者任何其它hadoop支持的文件系统。

代码示例:

>>> txt.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b).saveAsTextFile("file:///tmp/out")

查看输出文件:

$cat /tmp/out/part-00001
(u'bag', 2)
(u'apple', 1)
(u'cat', 3)

saveAsSequenceFile

将数据集的元素,以Hadoop sequencefile的格式,保存到指定的目录下,本地系统,HDFS或者任何其它hadoop支持的文件系统。这个只限于由key-value对组成,并实现了Hadoop的Writable接口,或者隐式的可以转换为Writable的RDD。

countByKey

对(K,V)类型的RDD有效,返回一个(K,Int)对的Map,表示每一个key对应的元素个数。

代码示例:

>>> txt.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).countByKey()
defaultdict(<type 'int'>, {u'bag': 2, u'apple': 1, u'cat': 3})

foreach

在数据集的每一个元素上,运行函数func进行更新。这通常用于边缘效果,例如更新一个累加器,或者和外部存储系统进行交互。

代码示例:

>>> def func(line): print line
>>> txt.foreach(lambda line: func(line))
apple
bag bag
cat cat cat

4. 其他

文中未提及的transformation和action函数可以通过如下命令查询:

>>> dir(txt)
['__add__', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_computeFractionForSampleSize', '_defaultReducePartitions', '_id', '_jrdd', '_jrdd_deserializer', '_memory_limit', '_pickled', '_reserialize', '_to_java_object_rdd', 'aggregate', 'aggregateByKey', 'cache', 'cartesian', 'checkpoint', 'coalesce', 'cogroup', 'collect', 'collectAsMap', 'combineByKey', 'context', 'count', 'countApprox', 'countApproxDistinct', 'countByKey', 'countByValue', 'ctx', 'distinct', 'filter', 'first', 'flatMap', 'flatMapValues', 'fold', 'foldByKey', 'foreach', 'foreachPartition', 'fullOuterJoin', 'getCheckpointFile', 'getNumPartitions', 'getStorageLevel', 'glom', 'groupBy', 'groupByKey', 'groupWith', 'histogram', 'id', 'intersection', 'isCheckpointed', 'isEmpty', 'is_cached', 'is_checkpointed', 'join', 'keyBy', 'keys', 'leftOuterJoin', 'lookup', 'map', 'mapPartitions', 'mapPartitionsWithIndex', 'mapPartitionsWithSplit', 'mapValues', 'max', 'mean', 'meanApprox', 'min', 'name', 'partitionBy', 'partitioner', 'persist', 'pipe', 'randomSplit', 'reduce', 'reduceByKey', 'reduceByKeyLocally', 'repartition', 'repartitionAndSortWithinPartitions', 'rightOuterJoin', 'sample', 'sampleByKey', 'sampleStdev', 'sampleVariance', 'saveAsHadoopDataset', 'saveAsHadoopFile', 'saveAsNewAPIHadoopDataset', 'saveAsNewAPIHadoopFile', 'saveAsPickleFile', 'saveAsSequenceFile', 'saveAsTextFile', 'setName', 'sortBy', 'sortByKey', 'stats', 'stdev', 'subtract', 'subtractByKey', 'sum', 'sumApprox', 'take', 'takeOrdered', 'takeSample', 'toDF', 'toDebugString', 'toLocalIterator', 'top', 'treeAggregate', 'treeReduce', 'union', 'unpersist', 'values', 'variance', 'zip', 'zipWithIndex', 'zipWithUniqueId']

查询具体函数的使用文档:

>>> help(txt.zipWithIndex)
Help on method zipWithIndex in module pyspark.rdd: zipWithIndex(self) method of pyspark.rdd.RDD instance
Zips this RDD with its element indices. The ordering is first based on the partition index and then the
ordering of items within each partition. So the first item in
the first partition gets index 0, and the last item in the last
partition receives the largest index. This method needs to trigger a spark job when this RDD contains
more than one partitions. >>> sc.parallelize(["a", "b", "c", "d"], 3).zipWithIndex().collect()
[('a', 0), ('b', 1), ('c', 2), ('d', 3)]
(END)

图解Spark API的更多相关文章

  1. 《图解Spark:核心技术与案例实战》作者经验谈

    1,看您有维护博客,还利用业余时间著书,在技术输出.自我提升以及本职工作的时间利用上您有没有什么心得和大家分享?(也可以包含一些您写书的小故事.)回答:在工作之余能够写博客.著书主要对技术的坚持和热爱 ...

  2. Spark:将RDD[List[String,List[Person]]]中的List[Person]通过spark api保存为hdfs文件时一直出现not serializable task,没办法找到"spark自定义Kryo序列化输入输出API"

    声明:本文转自<在Spark中自定义Kryo序列化输入输出API>   在Spark中内置支持两种系列化格式:(1).Java serialization:(2).Kryo seriali ...

  3. [Dynamic Language] pyspark Python3.7环境设置 及py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe解决!

    pyspark Python3.7环境设置 及py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spa ...

  4. 03、IDEA下Spark API编程

    03.IDEA下Spark API编程 3.1 编程实现Word Count 3.1.1 创建Scala模块 3.1.2 添加maven支持,并引入spark依赖 <?xml version=& ...

  5. spark api之一:Spark官方文档 - 中文翻译

    转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述(Overview) 2 引入Spark(Linking with Spark) 3 初始化Spark(Initi ...

  6. py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe. : java.lang.IllegalArgumentException: Unsupported class file major version 55

    今天小编用Python编写Spark程序报了如下异常: py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apach ...

  7. 调用spark API,监控任务的进度

    我们现在需要监控datapre0这个任务每一次执行的进度,操作如下: 1. 如图所示,打开spark管理页面,找到对应的任务,点击任务名datapre0 2. 进去之后,获得对应IP和端口  3. 访 ...

  8. Spark RDD :Spark API--图解Spark API

    面试题引出: 简述Spark的宽窄依赖,以及Spark如何划分stage,每个stage又根据什么决定task个数? Stage:根据RDD之间的依赖关系的不同将Job划分成不同的Stage,遇到一个 ...

  9. 《图解Spark:核心技术与案例实战》介绍及书附资源

    本书中所使用到的测试数据.代码和安装包放在百度盘提供 下载 ,地址为https://pan.baidu.com/s/1o8ydtKA 密码:imaa 另外在百度盘提供本书附录  下载 ,地址为http ...

随机推荐

  1. 【.net 深呼吸】细说CodeDom(3):命名空间

    在上一篇文章中,老周介绍了表达式和语句,尽管老周没有把所有的内容都讲一遍,但相信大伙至少已经掌握基本用法.在本文中,咱们继续探讨 CodeDom 方面的奥秘,这一次咱们聊聊命名空间. 在开始之前,老周 ...

  2. 闰秒导致MySQL服务器的CPU sys过高

    今天,有个哥们碰到一个问题,他有一个从库,只要是启动MySQL,CPU使用率就非常高,其中sys占比也比较高,具体可见下图. 注意:他的生产环境是物理机,单个CPU,4个Core. 于是,他抓取了CP ...

  3. Asp.Net WebApi核心对象解析(下篇)

    在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...

  4. CSS3 3D立方体效果-transform也不过如此

    CSS3系列已经学习了一段时间了,第一篇文章写了一些css3的奇技淫巧,原文戳这里,还获得了较多网友的支持,在此谢过各位,你们的支持是我写文章最大的动力^_^. 那么这一篇文章呢,主要是通过一个3D立 ...

  5. Hyper-V 激活Windows系统重启后黑屏的解决方法 + 激活方法

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...

  6. 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo

    有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ...

  7. Vue-Router 页面正在加载特效

    Vue-Router 页面正在加载特效 如果你在使用 Vue.js 和 Vue-Router 开发单页面应用.因为每个页面都是一个 Vue 组件,你需要从服务器端请求数据,然后再让 Vue 引擎来渲染 ...

  8. SQL Server-聚焦计算列或计算列持久化查询性能(二十二)

    前言 上一节我们详细讲解了计算列以及计算列持久化的问题,本节我们依然如前面讲解来看看二者查询性能问题,简短的内容,深入的理解,Always to review the basics. 持久化计算列比非 ...

  9. 基于RN开发的一款视频配音APP(开源)

    在如今React.ng.vue三分天下的格局下,不得不让自己加快学习的脚步.虽然经常会陷入各种迷茫,学得越多会发现不会的东西也被无限放大,不过能用新的技术作出一些小项目小Demo还是会给自己些许自信与 ...

  10. python 入门笔记

    1.pip包安装 pip install *** pip 中http和https代理设置(/etc/profile) 2.强制保存 :w !sudo tee % 3.cffi是python调用C的包 ...