目录
一、windows下配置pyspark环境
1.1 jdk下载安装
1.2 Scala下载安装
1.3 spark下载安装
1.4 Hadoop下载安装
1.5 pyspark下载安装
1.6 anaconda下载安装
1.7 测试环境是否搭建成功
二、pyspark原理简介
三、pyspark使用语法
3.1 RDD的基本操作
3.2 DataFrame的基本操作
3.3 pyspark.sql.functions中的方法简介
3.4 窗口函数的使用
Pyspark学习笔记
一、windows下配置pyspark环境
在python中使用pyspark并不是单纯的导入pyspark包就可以实现的。需要由不同的环境共同搭建spark环境,才可以在python中使用pyspark。
搭建pyspark所需环境:
python3,jdk,spark,Scala,Hadoop(可选)
1.1 jdk下载安装
下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
打开Windows中的环境变量:
创建JAVA_HOME:C:\Program Files\Java\jdk1.8.0_181
创建CLASSPATH:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
在Path添加:%JAVA_HOME%\bin;
测试是否安装成功:打开cmd命令行,输入java -version
1.2 Scala下载安装
下载地址:https://downloads.lightbend.com/scala/2.12.8/scala-2.12.8.msi
下载后进行安装
创建SCALA_HOME: C:\Program Files (x86)\scala
Path添加:;%SCALA_HOME%\bin; %JAVA_HOME%\bin;;%HADOOP_HOME%\bin
测试是否安装成功:打开cmd命令行,输入scala -version
1.3 spark下载安装
下载地址:http://mirror.bit.edu.cn/apache/spark/spark-3.0.0-preview2/spark-3.0.0-preview2-bin-hadoop2.7.tgz
也可以选择下载指定版本:http://spark.apache.org/downloads.html
下载好之后解压放在随便一个目录下即可,但是目录名不可以有空格。
环境变量:
创建SPARK_HOME:D:\spark-2.2.0-bin-hadoop2.7
Path添加:%SPARK_HOME%\bin
测试是否安装成功:打开cmd命令行,输入spark-shell
spark-shell时报错:error not found:value sqlContext。参考:https://www.liyang.site/2017/04/19/20170419-spark-error-01/
或者是路径中有空格所致。
1.4 Hadoop下载安装
如果你需要去hdfs取数据的话,就应该先装hadoop。对于spark和hadoop的关系,可以移步这篇博客:Spark是否会替代Hadoop?
https://blog.csdn.net/yjcyyl062c/article/details/84772829
下载地址:
http://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz
解压到指定目录即可。
环境变量:
创建HADOOP_HOME:D:\hadoop-2.7.7
Path添加:%HADOOP_HOME%\bin
测试是否安装成功:打开cmd命令行,输入hadoop
hadoop测试时报错:Error: JAVA_HOME is incorrectly set。参考:https://blog.csdn.net/qq_24125575/article/details/76186309
1.5 pyspark下载安装
python下安装pyspark,可以先去官网上将pyspark下载之后,再进行安装。避免超时
下载地址:https://pypi.tuna.tsinghua.edu.cn/packages/9a/5a/271c416c1c2185b6cb0151b29a91fff6fcaed80173c8584ff6d20e46b465/pyspark-2.4.5.tar.gz
下载之后使用pip install pyspark-2.4.5.tar.gz即可安装。
1.6 anaconda下载安装
1.进入Anaconda官网下载:https://www.anaconda.com/distribution/
2.直接双击运行安装包即可。
3.一直下一步。
4.测试是否安装成功:命令行下输入conda --version
1.7 测试环境是否搭建成功
测试整体环境是否搭建完成:
新建py文件并包含下面的测试代码:
from pyspark import SparkContext
sc = SparkContext("local", "count app")
words = sc.parallelize(
["scala",
"java",
"hadoop",
"spark",
"akka",
"spark vs hadoop",
"pyspark",
"pyspark and spark"
])
counts = words.count()
print("Number of elements in RDD -> %i" % counts)
注意:建议在代码之前加上下面这两行代码,可以自动寻找spark的安装位置,是在py文件的最上端加入。
import findspark
findspark.init()
在本地电脑的jupyter notebook上进行spark操作时如果报jvm的错误,说明在jupyter中没有配置好spark的环境,可以考虑使用下面这种方式来加载spark的环境。在jupyter中新建一个python3文件,输入以下代码块
import findspark
findspark.init()
import os
import sys
spark_name = os.environ.get('SPARK_HOME',None)
if not spark_name:
raise ValueErrorError('spark环境没有配置好')
sys.path.insert(0,os.path.join(spark_name,'python'))
sys.path.insert(0,os.path.join(spark_name,'D:\spark-3.0.0-preview2-bin-hadoop2.7\python\lib\py4j-0.10.8.1-src.zip'))
#(py4j-0.10.6-src.zip位于D:spark-2.3.0-bin-hadoop2.7中python文件夹中lib文件夹内,请根据自己的版本更改)
然后运行,就可以在jupyter中愉快的使用spark啦。
mac下配置此环境可以参考下面这篇文章:
https://blog.csdn.net/wapecheng/article/details/108071538
二、pyspark原理简介
pyspark的实现机制可以用下面这张图来表示
在python driver端,SparkContext利用Py4J启动一个JVM并产生一个JavaSparkContext。Py4J只使用在driver端,用于本地python与java SparkContext objects的通信。大量数据的传输使用的是另一个机制。
RDD在python下的转换会被映射成java环境下PythonRDD。在远端worker机器上,PythonRDD对象启动一些子进程并通过pipes与这些子进程通信,以此send用户代码和数据。
三、pyspark使用语法
在Spark2.0之前, SparkContext 是所有 Spark 功能的结构, 驱动器(driver) 通过SparkContext 连接到集群 (通过resource manager), 因为在2.0之前, RDD就是Spark的基础。如果需要建立SparkContext,则需要SparkConf,通过Conf来配置SparkContext的内容。
其中:
setAppName(), 是你的程序在集群上的名字
setMaster(), 你的Spark运行的模式 ‘local’表示本地模式
而在Spark2.0之后,Spark Session也是Spark 的一个入口, 为了引入dataframe和dataset的API, 同时保留了原来SparkContext的functionality, 如果想要使用 HIVE,SQL,Streaming的API, 就需要Spark Session作为入口。
spark = SparkSession.builder.appName('testSQL')\
.config('spark.some.config.option','some-value')\
.getOrCreate()
写一个小小的例子,创建一个SparkContext对象并统计一个文件中的行数。
import findspark
findspark.init()
from pyspark import SparkContext
logFile = r"C:\Users\Administrator\Desktop\README.md"
sc = SparkContext("local", "first app")
logData = sc.textFile(logFile).count()
print(logData)
3.1 RDD的基本操作
Spark的核心是RDD(Resilient Distributed Dataset)即弹性分布式数据集,属于一种分布式的内存系统的数据集应用。Spark主要优势就是来自RDD本身的特性,RDD能与其他系统兼容,可以导入外部存储系统的数据集,例如,HDFS、HBase或者其他Hadoop数据源。它们是在多个节点上运行和操作以在集群上进行并行处理的元素。RDD是不可变元素,这意味着一旦创建了RDD,就无法对其进行更改。RDD也具有容错能力,因此在发生任何故障时,它们会自动恢复。你可以对这些RDD应用多个操作来完成某项任务
要对这些RDD进行操作,有两种方法:
• Transformation
• Action
转换 - 这些操作应用于RDD以创建新的RDD。Filter,groupBy和map是转换的示例。
操作 - 这些是应用于RDD的操作,它指示Spark执行计算并将结果发送回驱动程序。
使用sparkcontext读取文件:
- data_rdd = sc.textFiles(‘xxxxxxx.txt’) # 读入文件内容,返回的东西是rdd
- path_data_rdd = sc.wholeTextFile((‘xxxxxxx.txt’)) # 不仅读入文件内容,还会读入文件的路径path
基本操作及示例:
-
count() 返回RDD中的元素个数
from pyspark import SparkContext sc = SparkContext("local", "count app") words = sc.parallelize( ["scala", "java", "hadoop", "spark", "akka", "spark vs hadoop", "pyspark", "pyspark and spark" ]) counts = words.count() print("Number of elements in RDD -> %i" % counts)
-
collect() 返回RDD中的所有元素,即转换为python数据类型
from pyspark import SparkContext sc = SparkContext("local", "collect app") words = sc.parallelize( ["scala", "java", "hadoop", "spark", "akka", "spark vs hadoop", "pyspark", "pyspark and spark" ]) coll = words.collect() print("Elements in RDD -> %s" % coll)
- foreach(func)
仅返回满足foreach内函数条件的元素。在下面的示例中,我们在foreach中调用print函数,该函数打印RDD中的所有元素from pyspark import SparkContext sc = SparkContext("local", "ForEach app") words = sc.parallelize ( ["scala", "java", "hadoop", "spark", "akka", "spark vs hadoop", "pyspark", "pyspark and spark"] ) def f(x): print(x) fore = words.foreach(f)
- filter(f) 返回一个包含元素的新RDD,它满足过滤器内部的功能。在下面的示例中,我们过滤掉包含’'spark’的字符串。
from pyspark import SparkContext sc = SparkContext("local", "Filter app") words = sc.parallelize( ["scala", "java", "hadoop", "spark", "akka", "spark vs hadoop", "pyspark", "pyspark and spark"] ) words_filter = words.filter(lambda x: 'spark' in x) filtered = words_filter.collect() print("Fitered RDD -> %s" % (filtered))
-
map(f, preservesPartitioning = False)
通过将该函数应用于RDD中的每个元素来返回新的RDD。在下面的示例中,我们形成一个键值对,并将每个字符串映射为值1from pyspark import SparkContext sc = SparkContext("local", "Map app") words = sc.parallelize( ["scala", "java", "hadoop", "spark", "akka", "spark vs hadoop", "pyspark", "pyspark and spark"] ) words_map = words.map(lambda x: (x, 1)) mapping = words_map.collect() print("Key value pair -> %s" % (mapping))
-
reduce(f) 执行指定的可交换和关联二元操作后,将返回RDD中的元素。
在下面的示例中,我们从运算符导入add包并将其应用于’num’以执行简单的加法运算。说白了和Python的reduce一样:假如有一组整数[x1,x2,x3],利用reduce执行加法操作add,对第一个元素执行add后,结果为sum=x1,然后再将sum和x2执行add,sum=x1+x2,最后再将x2和sum执行add,此时sum=x1+x2+x3。
from pyspark import SparkContext from operator import add sc = SparkContext("local", "Reduce app") nums = sc.parallelize([1, 2, 3, 4, 5]) adding = nums.reduce(add) print("Adding all the elements -> %i" % (adding))
- join(other, numPartitions = None) 它返回RDD,其中包含一对带有匹配键的元素以及该特定键的所有值。
from pyspark import SparkContext sc = SparkContext("local", "Join app") x = sc.parallelize([("spark", 1), ("hadoop", 4)]) y = sc.parallelize([("spark", 2), ("hadoop", 5)]) joined = x.join(y) final = joined.collect() print( "Join RDD -> %s" % (final))
下面换一组数据进行操作。
import findspark
findspark.init()
from pyspark import SparkConf, SparkContext
sc = SparkContext()
intRDD = sc.parallelize([3,1,2,5,5])
stringRDD = sc.parallelize(['Apple','Orange','Grape'