以下是个人理解,一切以官网文档为准。

http://spark.apache.org/docs/latest/api/python/pyspark.html

在开始之前,我先介绍一下,RDD是什么?

RDD是Spark中的抽象数据结构类型,任何数据在Spark中都被表示为RDD。从编程的角度来看,RDD可以简单看成是一个数组。和普通数组的区别是,RDD中的数据是分区存储的,这样不同分区的数据就可以分布在不同的机器上,同时可以被并行处理。因此,Spark应用程序所做的无非是把需要处理的数据转换为RDD,然后对RDD进行一系列的变换和操作从而得到结果。

  创建RDD:

>>> sc.parallelize([1,2,3,4,5], 3)  #意思是将数组中的元素转换为RDD,并且存储在3个分区上[1]、[2,3]、[4,5]。如果是4个分区:[1]、[2]、[3]、[4,5]

  上面这种是数组创建,也可以从文件系统或者HDFS中的文件创建出来,后面会讲到。

只要搞懂了spark的函数们,你就成功了一大半。

spark的函数主要分两类,TransformationsActions。Transformations为一些数据转换类函数,actions为一些行动类函数:

转换:转换的返回值是一个新的RDD集合,而不是单个值。调用一个变换方法,不会有任何求值计算,它只获取一个RDD作为参数,然后返回一个新的RDD。

行动:行动操作计算并返回一个新的值。当在一个RDD对象上调用行动函数时,会在这一时刻计算全部的数据处理查询并返回结果值。

下面介绍spark常用的Transformations, Actions函数:

Transformations

map(func [, preservesPartitioning=False])  --- 返回一个新的分布式数据集,这个数据集中的每个元素都是经过func函数处理过的。

>>> data = [1,2,3,4,5]
>>> distData = sc.parallelize(data).map(lambda x: x+1).collect()
#结果:[2,3,4,5,6]

filter(func)  --- 返回一个新的数据集,这个数据集中的元素是通过func函数筛选后返回为true的元素(简单的说就是,对数据集中的每个元素进行筛选,如果符合条件则返回true,不符合返回false,最后将返回为true的元素组成新的数据集返回)。

>>> rdd = sc.parallelize(data).filter(lambda x:x%2==0).collect()
#结果:[2, 4]

flatMap(func [, preservesPartitioning=False])  --- 类似于map(func), 但是不同的是map对每个元素处理完后返回与原数据集相同元素数量的数据集,而flatMap返回的元素数不一定和原数据集相同。each input item can be mapped to 0 or more output items (so funcshould return a Seq rather than a single item)

#### for flatMap()
>>> rdd = sc.parallelize([2,3,4])
>>> sorted(rdd.flatMap(lambda x: range(1,x)).collect())
#结果:[1, 1, 1, 2, 2, 3]
>>> sorted(rdd.flatMap(lambda x:[(x,x), (x,x)]).collect())
#结果:[(2, 2), (2, 2), (3, 3), (3, 3), (4, 4), (4, 4)] #### for map()
>>> rdd = sc.parallelize([2,3,4])
>>> sorted(rdd.flatMap(lambda x: range(1,x)).collect())
#结果:[[1], [1, 2], [1, 2, 3]]
>>> sorted(rdd.flatMap(lambda x:[(x,x), (x,x)]).collect())
#结果:[[(2, 2), (2, 2)], [(3, 3), (3, 3)], [(4, 4), (4, 4)]]

mapPartitions(func [, preservesPartitioning=False])  ---mapPartitions是map的一个变种。map的输入函数是应用于RDD中每个元素,而mapPartitions的输入函数是应用于每个分区,也就是把每个分区中的内容作为整体来处理的。

>>> rdd = sc.parallelize([1,2,3,4,5], 3)
>>> def f(iterator): yield sum(iterator)
>>> rdd.mapPartitions(f).collect()
#结果:[1,5,9]

mapPartitionsWithIndex(func [, preservesPartitioning=False])  ---Similar to mapPartitions, but takes two parameters. The first parameter is the index of the partition and the second is an iterator through all the items within this partition. The output is an iterator containing the list of items after applying whatever transformation the function encodes.

>>> rdd = sc.parallelize([1,2,3,4,5], 3)
>>> def f(splitIndex, iterator): yield splitIndex
>>> rdd.mapPartitionsWithIndex(f).collect()
#结果:[0,1,2] #三个分区的索引

reduceByKey(func [numPartitions=NonepartitionFunc=<function portable_hash at 0x7fa664f3cb90>])  --- reduceByKey就是对元素为kv对的RDD中Key相同的元素的value进行reduce,因此,key相同的多个元素的值被reduce为一个值,然后与原RDD中的key组成一个新的kv对。

>>> from operator import add
>>> rdd = sc.parallelize([("a", 1), ("b", 1), ("a", 1)])
>>> sorted(rdd.reduceByKey(add).collect())
>>> #或者 sorted(rdd.reduceByKey(lambda a,b:a+b).collect())
#结果:[('a', 2), ('b', 1)]

aggregateByKey(zeroValue)(seqOp, combOp [, numPartitions=None])  ---

sortByKey([ascending=True, numPartitions=None, keyfunc=<function <lambda> at 0x7fa665048c80>])  --- 返回排序后的数据集。该函数就是队kv对的RDD数据进行排序,keyfunc是对key进行处理的函数,如非需要,不用管。

>>> tmp = [('a', 1), ('b', 2), ('1', 3), ('D', 4)]
>>> sc.parallelize(tmp).sortByKey(True, 1).collect()
#结果: [('1', 3), ('D', 4), ('a', 1), ('b', 2)]
>>> sc.parallelize(tmp).sortByKey(True, 2, keyfunc=lambda k:k.lower()).collect()
#结果:[('1', 3), ('a', 1), ('b', 2), ('D', 4)]
#注意,比较两个结果可看出,keyfunc对键的处理只是在数据处理的过程中起作用,不能真正的去改变键名

join(otherDataset [, numPartitions=None])  --- join就是对元素为kv对的RDD中key相同的value收集到一起组成(v1,v2),然后与原RDD中的key组合成一个新的kv对,返回。

>>> x = sc.parallelize([("a", 1), ("b", 4)])
>>> y = sc.parallelize([("a", 2), ("a", 3)])
>>> sorted(x.join(y).collect())
#结果:[('a', (1, 2)), ('a', (1, 3))]

cartesian(otherDataset)  --- 返回一个笛卡尔积的数据集,这个数据集是通过计算两个RDDs得到的。

>>> x = sc.parallelize([1,2,3])
>>> y = sc.parallelize([4,5])
>>> x.cartesian(y).collect()
#结果:[(1, 4), (1, 5), (2, 4), (2, 5), (3, 4), (3, 5)]

Action (这里只讲支持python的,java和scala的后面用到了在做详解,当然支持python就一定支持java和scala)

reduce(func)  --- reduce将RDD中元素两两传递给输入函数,同时产生一个新的值,新产生的值与RDD中下一个元素再被传递给输入函数直到最后只有一个值为止。

>>> from operator import add
>>> sc.parallelize([1,2,3,4,5]).reduce(add)
# 结果:15

collect()  --- 返回RDD中的数据,以list形式。

>>> sc.parallelize([1,2,3,4,5]).collect()
#结果:[1,2,3,4,5]

count()  --- 返回RDD中的元素个数。

>>> sc.parallelize([1,2,3,4,5]).count
#结果:5

first()  --- 返回RDD中的第一个元素。

>>> sc.parallelize([1,2,3,4,5]).first()
#结果:1

take(n)  --- 返回RDD中前n个元素。

>>> sc.parallelize([1,2,3,4,5]).take(2)
#结果:[1,2]

takeOrdered(n [, key=None])  --- 返回RDD中前n个元素,但是是升序(默认)排列后的前n个元素,或者是通过key函数指定后的RDD(这个key我也没理解透,后面在做详解)

>>> sc.parallelize([9,7,3,2,6,4]).takeOrdered(3)
#结果:[2,3,4]
>>> sc.parallelize([9,7,3,2,6,4]).takeOrdered(3, key=lambda x:-x)
#结果:[9,7,6]

saveAsTextFile(path [, compressionCodecClass=None])  --- 该函数将RDD保存到文件系统里面,并且将其转换为文本行的文件中的每个元素调用 tostring 方法。

parameters:  path - 保存于文件系统的路径

       compressionCodecClass - (None by default) string i.e. “org.apache.hadoop.io.compress.GzipCodec”

>>> tempFile = NamedTemporaryFile(delete=True)
>>> tempFile.close()
>>> sc.parallelize(range(10)).saveAsTextFile(tempFile.name)
>>> from fileinput import input
>>> from glob import glob
>>> ''.join(sorted(input(glob(tempFile.name + "/part-0000*"))))
'0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n'

Empty lines are tolerated when saving to text files:

>>> tempFile2 = NamedTemporaryFile(delete=True)
>>> tempFile2.close()
>>> sc.parallelize(['', 'foo', '', 'bar', '']).saveAsTextFile(tempFile2.name)
>>> ''.join(sorted(input(glob(tempFile2.name + "/part-0000*"))))
'\n\n\nbar\nfoo\n'

Using compressionCodecClass:

>>> tempFile3 = NamedTemporaryFile(delete=True)
>>> tempFile3.close()
>>> codec = "org.apache.hadoop.io.compress.GzipCodec"
>>> sc.parallelize(['foo', 'bar']).saveAsTextFile(tempFile3.name, codec)
>>> from fileinput import input, hook_compressed
>>> result = sorted(input(glob(tempFile3.name + "/part*.gz"), openhook=hook_compressed))
>>> b''.join(result).decode('utf-8')
u'bar\nfoo\n'

countByKey()  --- 返回一个字典(key,count),该函数操作数据集为kv形式的数据,用于统计RDD中拥有相同key的元素个数。

>>> defdict = sc.parallelize([("a",1), ("b",1), ("a", 1)]).countByKey()
>>> defdict
#结果:defaultdict(<type 'int'>, {'a': 2, 'b': 1})
>>> defdict.items()
#结果:[('a', 2), ('b', 1)]

countByValue()  --- 返回一个字典(value,count),该函数操作一个list数据集,用于统计RDD中拥有相同value的元素个数。

>>> sc.parallelize([1,2,3,1,2,5,3,2,3,2]).countByValue().items()
#结果:[(1, 2), (2, 4), (3, 3), (5, 1)]

foreach(func)  --- 运行函数func来处理RDD中的每个元素,这个函数常被用来updating an Accumulator或者与外部存储系统的交互。

>>> def f(x): print(x)
>>> sc.parallelize([1, 2, 3, 4, 5]).foreach(f)
#note: 打印是随机的,并不是一定按1,2,3,4,5的顺序打印

spark 常用函数介绍(python)的更多相关文章

  1. [MFC美化] SkinMagic使用详解2- SkinMagic常用函数介绍

    SkinMagic常用函数介绍 (1)InitSkinMagicLib函数:初始化SkinMagic int InitSkinMagicLib( //初始化SkinMagic工具库 HINSTANCE ...

  2. MySQL常用函数介绍

    MySQL常用函数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作符介绍 1>.操作符优先级 mysql; +----------+ | +----------+ ...

  3. go语言之进阶篇字符串操作常用函数介绍

    下面这些函数来自于strings包,这里介绍一些我平常经常用到的函数,更详细的请参考官方的文档. 一.字符串操作常用函数介绍 1.Contains func Contains(s, substr st ...

  4. MySQL 常用函数介绍

    MySQL 基础篇 三范式 MySQL 军规 MySQL 配置 MySQL 用户管理和权限设置 MySQL 常用函数介绍 MySQL 字段类型介绍 MySQL 多列排序 MySQL 行转列 列转行 M ...

  5. Python数据分析--Numpy常用函数介绍(2)

    摘要:本篇我们将以分析历史股价为例,介绍怎样从文件中载入数据,以及怎样使用NumPy的基本数学和统计分析函数.学习读写文件的方法,并尝试函数式编程和NumPy线性代数运算,来学习NumPy的常用函数. ...

  6. SQL SERVER系统表和常用函数介绍

    sysaltfiles 主数据库 保存数据库的文件 syscharsets 主数据库 字符集与排序顺序sysconfigures 主数据库 配置选项syscurconfigs 主数据库 当前配置选项s ...

  7. (转)postgis常用函数介绍(一)

    http://blog.csdn.net/gisshixisheng/article/details/47701237 概述: 在进行地理信息系统开发的过程中,常用的空间数据库有esri的sde,po ...

  8. promql 常用函数介绍

    Metrics类型 根据不同监控指标之间的差异,Prometheus定义了4中不同的指标类型(metric type):Counter(计数器).Gauge(仪表盘).Histogram(直方图).S ...

  9. 性能测试基础-开门篇3(LR常用函数介绍)

    LR常用的函数,协议不一样函数会不一样,这里简单的介绍下HTTP\WEBSERVICE\SOCKET协议常用函数: HTTP: web_set_max_html_param_len("102 ...

随机推荐

  1. Java API 之 SPI机制

    SPI SPI全称是service provider interface,是Java定义的一套服务发现机制,如图: 调用方只需要面向接口,接口的实现由第三方自己去实现,服务启动的时候会自动去发现该服务 ...

  2. 基于【 springBoot +springCloud+vue 项目】二 || 后端框架详解

     前言 在上一篇中,我们搭建了一个-API服务提供接口模块,目的为了提供了消费方进行调用.为什么不直接在service层直接提供调用接口,而是重新创建一个接口层模块?首先我们需要对Feign有所了解. ...

  3. 在Android8.0以上收不到广播问题(AppWidget)

    对Intent指定组件 //安卓8.0必须添加 intent.setComponent(new ComponentName(context,MyAppWidgetProvider.class)); 问 ...

  4. ActiveMQ入门系列三:发布/订阅模式

    在上一篇<ActiveMQ入门系列二:入门代码实例(点对点模式)>中提到了ActiveMQ中的两种模式:点对点模式(PTP)和发布/订阅模式(Pub & Sub),详细介绍了点对点 ...

  5. 在eclipse导入项目的步骤

    1. Import 2. Next 3. 确定  选中copy projects into workspace    Finish 这样项目就导入进来了. 4.导入jar包 Configure Bui ...

  6. Google C++单元测试框架GoogleTest---AdvancedGuide(译文)

    上篇在这里: 下篇在这里.

  7. <meta http-equiv="X-UA-Compatible" content="IE=edge">详解

    X-UA-Compatible是针对IE8新加的一个设置,对于IE8之外的浏览器是不识别的. 这个区别与content="IE=7"在无论页面是否包含<!DOCTYPE> ...

  8. Java NIO 学习笔记一

    缓冲区操作 进程执行I/O操作,归结起来就是向操作系统发出请求,它要么把缓存区例的数据排干(写),要么用数据把数据区填满(读).进程使用这一机制处理所有数据进出操作. 进程使用read()系统调用,要 ...

  9. 【bzoj2141】排队 [国家集训队2011]排队(树套树)

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...

  10. Educational Codeforces Round 50 (Rated for Div. 2) F - Relatively Prime Powers(数学+容斥)

    题目链接:http://codeforces.com/contest/1036/problem/F 题意: 题解:求在[2,n]中,x != a ^ b(b >= 2 即为gcd)的个数,那么实 ...