Spark (Python版) 零基础学习笔记(一)—— 快速入门
由于Scala才刚刚开始学习,还是对python更为熟悉,因此在这记录一下自己的学习过程,主要内容来自于spark的官方帮助文档,这一节的地址为:
http://spark.apache.org/docs/latest/quick-start.html
文章主要是翻译了文档的内容,但也在里边加入了一些自己在实际操作中遇到的问题及解决的方案,和一些补充的小知识,一起学习。
环境:Ubuntu 16.04 LTS,Spark 2.0.1, Hadoop 2.7.3, Python 3.5.2,
利用spark shell进行交互式分析
1. 基础
首先打开spark与python交互的API
$ cd /usr/local/spark
$ ./bin/pyspark
Spark最重要的一个概念就是RDD(Resilient Distributed Dataset),弹性分布式数据集。RDD可以利用Hadoop的InputFormats创建,或者从其他RDD转换。
这里,作为入门,我们利用spark安装后文件夹中自带的README.md(此文件位置为/usr/local/spark/README.md)文件作为例子,学习如何创建一个新的RDD。
创建新的RDD:
>>> textFile = sc.textFile(“README.md”)
RDD支持两种类型的操作,actions和transformations:
actions: 在数据集上运行计算后返回值
transformations: 转换, 从现有数据集创建一个新的数据集
RDD可以有执行一系列的动作(actions),这些动作可以返回值(values),转换(transformations),或者指向新的RDD的指针。下边学习RDD的一些简单的动作:
>>> textFile.count() # 计数,返回RDD中items的个数,这里就是README.md的总行# 数
99
>>> textFile.first() # RDD中的第一个item,这里就是文件README.md的第一行
u'# Apache Spark'
注意:如果之前是从/usr/local/spark启动pyspark,然后读取README.md文件的,如果执行count语句,会出现以下错误:
py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe.
: org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://localhost:9000/user/spark/README.md
这是因为在使用相对路径时,系统默认是从hdfs://localhost:9000/目录下读取README.md文件的,但是README.md文件并不在这一目录下,所以sc.textFile()必须使用绝对路径,此时代码修改为:
>>> textFile = sc.textFile(“file:///usr/local/spark/README.md”)
99
下边尝试使用一个转换(transformation)。例如,使用filter这一转换返回一个新的RDD,这些RDD中的items都含有“Spark”字符串。
>>> linesWithSpark = textFile.filter(lambda line: “Spark” in line)
我们还可以将actions和transformation链接起来:
>>> textFile.filter(lambda line: “Spark” in line).count() # 有多好行含有“Spark”这一字符串
19
2. 更多的RDD操作
利用RDD的动作和转换能够完成很多复杂的计算。例如,我们希望找到含有最后单词的一句话:
>>> textFile.map(lambda line: len(line.split())).reduce(lambda a, b: a if (a>b) else b)
22
这个语句中,map函数将len(line.split())这一语句在所有line上执行,返回每个line所含有的单词个数,也就是将line都map到一个整数值,然后创建一个新的RDD。然后调用reduce,找到最大值。map和reduce函数里的参数是python中的匿名函数(lambda),事实上,我们这里也可以传递python中更顶层的函数。比如,我们先定义一个比较大小的函数,这样我们的代码会更容易理解:
>>> def max(a, b):
. . . if a > b:
. . . return a
. . . else:
. . . return b
. . .
>>> textFile.map(lambda line: len(line.split())).reduce(max)
22
Hadoop掀起了MapReduce的热潮。在spark中,能够更加容易的实现MapReduce
>>> wordCounts = textFile.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a+b)
上述语句中,利用flatMap, map和reduceByKey三个转换,计算文件README.md中每个单词出现的个数,并返回一个新的RDD,每个item的格式为(string, int),即单词和对应的出现次数。其中,
flatMap(func):与map相似,但是每个输入的item能够被map到0个或者更多的输出items上,也就是说func的返回值应当是一个Seq,而不是一个单独的item,上述语句中,匿名函数返回的就是一句话中所含的每个单词
reduceByKey(func):可以作用于使用“键-值”(K, V)形式存储的数据集上并返回一组新的数据集(K, V),其中,每个键的值为聚合使用func操作的结果,这里相当于python中字典的含义。上述语句中,相当于当某个单词出现一次时,就在这个单词的出现次数上加1,每个单词就是一个Key,reducByKey中的匿名函数计算单词的出现次数。
要收集上述语句的计算结果,可以使用collect这一动作:
>>> wordCounts.collect()
[(u'when', 1), (u'R,', 1), (u'including', 3), (u'computation', 1), ...]
3. 缓存Caching
Spark也支持将数据集存入集群范围的内存缓存中。这对于需要进行重复访问的数据非常有用,比如我们需要在一个小的数据集中执行查询操作,或者需要执行一个迭代算法(例如PageRank)。下面,利用之前命令中得到的linesWithSpark数据集,演示缓存这一操作过程:
>>> linesWithSpark.cache()
PythonRDD[26] at RDD at PythonRDD.scala:48
>>> linesWithSpark.count()
19
>>> linesWithSpark.count()
19
利用Spark去缓存一个100行的文件可能并没什么意义。但是有趣的是,这一系列的操作可以用于非常大的数据集上,甚至含有成千上万的节点的数据集。
4. 自含式应用程序(self-contained applications)
假设我们希望利用Spark API写一个自含式应用程序,我们可以利用Scala,Java或者Python完成。
下边,简单介绍一下怎样利用Python API (PySpark)写一个应用程序,命名为SimpleApp.py.
在spark所在目录下输入:
./bin/spark-submit --master local[4] SimpleApp.py
输出为:
Lines with a: 61, Lines with b: 27
此外,Spark自带很多例子,可以在spark目录下输入下列指令查看:
# For Scala and Java, use run-example: ./bin/run-example SparkPi # For Python examples, use spark-submit directly: ./bin/spark-submit examples/src/main/python/pi.py # For R examples, use spark-submit directly: ./bin/spark-submit examples/src/main/r/dataframe.R
Spark (Python版) 零基础学习笔记(一)—— 快速入门的更多相关文章
- Spark (Python版) 零基础学习笔记(二)—— Spark Transformations总结及举例
1. map(func) 将func函数作用到数据集的每个元素,生成一个新的分布式的数据集并返回 >>> a = sc.parallelize(('a', 'b', 'c')) &g ...
- CSS零基础学习笔记.
酸菜记 之 CSS的零基础. 这篇是我自己从零基础学习CSS的笔记加理解总结归纳的,如有不对的地方,请留言指教, 学前了解: CSS中字母是不分大小写的; CSS文件可以使用在各种程序文件中(如:PH ...
- C++ Primer学习笔记_1_快速入门
C++快速入门 一 编写简单程序 // main是操作系统唯一显示调用的函数int main() {/**return返回的值是一个状态指示器 0:成功 非0:返回错误给OS*以echo $?命令可以 ...
- python 零基础学习之路 02-python入门
不知不觉学习python已经两个月了,从一开始不知道如何对print的格式化,到现在可以手撸orm,这期间真的是 一个神奇的过程.为了巩固自己的基础知识,为后面的拓展埋下更好的伏笔,此文当以导师的博客 ...
- python+request 常用基础学习笔记
1.pycharm,避免控制台输出的json内容中文出现乱码. #注:乱码为Unicode格式:\u6d4b\u8bd5.加入如下代码后正确返回中文:测试 get_result = r.json() ...
- 跟我从零基础学习Unity3D开发--NGUI入门基础
英雄联盟(撸啊撸) QQ飞车 魔兽世界等等相信大家都玩过游戏吧,玩过那UI知道是什么吧?UI可能说得有点专业的话那么游戏中那些属性面板例如: 现在对UI有一定认识了吧!回想一下您玩过的游戏就一定知道什 ...
- 单片机零基础学习之从“点灯”入门STM32
本篇文章通过一个简单的例子来熟悉模块化编程以及利用库函数的方法进行开发使用STM32外设的基本流程. 首先,我们打开本讲的例程,在工程目录我们可以看到驱动分组下有 led.delay 两个.c源文件, ...
- 学习笔记-CCS-MSP430F5529[快速入门篇二]
由于2021的全国电赛延期了,从今天开始打算好好整理一下使用CCS编程的经验,本篇笔记会好好整理一下我备赛期间用CCS写的程序,包括外部中断,定时器部分的定时中断,定时器输入捕获,PWM波输出,UAR ...
- 学习笔记-CCS-MSP430F5529[快速入门篇一]
由于最近竞赛需要使用TI公司的MSP430系列芯片,本人在最近两天匆忙的学习了一下MSP430F5529(下文统一称作5529)的使用.写下本文是为了将这两天学习内容做一个复习,并且将学习过程中遇到的 ...
随机推荐
- mysql for visual
http://dev.mysql.com/downloads/file.php?id=458484
- 僵固式思维 OR 成长式思维
有意无意中,看到这样的一篇文章,觉得非常富有正能量,而且也比较有同感.而且,不仅仅对于职场暂时失落或者失意的人有帮助,就是对学生,也一样的.故特分享,以共勉之. 我想每个新人进入职场之后都会遇到的第一 ...
- 浅析C语言中assert的用法(转)
原文地址:http://www.jb51.net/article/39685.htm 以下是对C语言中assert的使用方法进行了介绍,需要的朋友可以参考下. assert宏的原型定义在<ass ...
- 【Azure Active Directory】单一登录 (SAML 协议)
Azure Active Directory 支持 SAML 2.0 Web 浏览器单一登录 (SSO) 配置文件. 若要请求 Azure Active Directory 对用户进行身份验证时,云服 ...
- ASP.NET MVC4 学习记录
之前在学习Artech的<ASP.NET MVC4框架揭秘>一书,学习过程中画了ASP.NET MVC4框架的草图,方便记忆.
- XE改变图标颜色
放一个image,load 一张png/..图片 再放一个FillRGBEffect, 将此控价拖到image下 改变FillRGBEffect的Color,就改变了image图标上的颜色. 原图为黑 ...
- 关于winform的appconfig的读写操作
public string ReadConfig() { List<string> list = new List<string>(); ExeConfigurationFil ...
- Nexus 私有仓库
Nexus3.6和Nexus2.x安装不同,2.x版本需要安装服务,再启动.而3.6版本则更加简单. 步骤如下: jdk环境:1.8 Nexus3.6解压(注意,路径不要带空格及中文),解压后有两个文 ...
- super() 的入门使用
在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: 1 2 3 4 5 ...
- C#帮助类:Base64
public class Base64 { #region Base64加密 ///<summary> ///Base64加密 ///</summary> ///<par ...