spark安装到pyspark应用
1.安装
本文主要针对python环境下的操作
首先要先安装下面内容:
JAVA (JDK)
Spark
Scala
Hadoop
PySpark
以上安装完成,保证配置环境变量:
安装步骤参考:https://blog.csdn.net/penyok/article/details/81483527
测试以上步骤都安装成功
2. pyspark应用
- RDD初始化的两种方法
import findspark
findspark.init()
import os
import pyspark
from pyspark import SparkConf
from pyspark.context import SparkContext
# 初始化RDD方法1
conf = SparkConf().setAppName("project1").setMaster("local[*]")
# # 以上面的名字配置初始化一个sparkcontext
sc = SparkContext.getOrCreate(conf)
# 当前环境内存中的list
li = [1, 2, 3, 4, 5, 6]
# 把上面list初始化成RDD
rdd = sc.parallelize(li)
print(rdd) # rdd对象
# 查看数据存的份数
print(rdd.getNumPartitions())
# 查看分区情况 collect()函数会把服务器数据取回本地
# print(rdd.glom().collect())
print('********************************')
# 初始化RDD方法二 直接将本地文件读到RDD Spark默认路径执行HDFS
datapath = '/dataset/people.txt'
cwd = os.getcwd()
print('返回当前目录', cwd)
conf = SparkConf().setAppName("project2").setMaster("local[*]")
# # 以上面的名字配置初始化一个sparkcontext
sc = SparkContext.getOrCreate(conf)
# path = "file://" + cwd + datapath windows下多加一个/
path = "file:///D:\python/dataset/people.txt"
# 读取单个文件
rdd = sc.textFile(path)
print(rdd)
print(rdd.first())
# 读取多个文件 得到的是元组 (文件名,内容)
rdd1 = sc.wholeTextFiles("file://" +'/' + cwd + '/dataset')
print(rdd1)
print(rdd1.first())
- RDD与RDD之间的操作
import findspark
findspark.init()
from pyspark.context import SparkContext
"""
如果你有2个RDD了,下面的这些操作方式组合得到1个RDD:
* **`rdd1.union(rdd2)`: 所有`rdd1`和`rdd2`中的item组合**
* **`rdd1.intersection(rdd2)`: `rdd1` 和 `rdd2`的交集**
* **`rdd1.substract(rdd2)`: 所有在`rdd1`中但不在`rdd2`中的item(差集)**
* **`rdd1.cartesian(rdd2)`: `rdd1` 和 `rdd2`中所有的元素笛卡尔乘积 **
"""
sc = SparkContext('local', 'rdd_rdd')
numbersRDD1 = sc.parallelize([1, 2, 3])
numbersRDD2 = sc.parallelize([2, 3, 4])
print(numbersRDD1.union(numbersRDD2).collect())
print(numbersRDD1.intersection(numbersRDD2).collect())
print(numbersRDD1.subtract(numbersRDD2).collect())
print(numbersRDD1.cartesian(numbersRDD2).collect())
[1, 2, 3, 2, 3, 4]
[2, 3]
[1]
[(1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4)]
- RDD transformations和actions
import findspark
findspark.init()
import os
import pyspark
from pyspark import SparkConf
from pyspark.context import SparkContext
"""
## RDD transformations和actions
* **`map()` 对RDD的每一个item都执行同一个操作**
* **`flatMap()` 对RDD中的item执行同一个操作以后得到一个list,然后以平铺的方式把这些list里所有的结果组成新的list**
* **`filter()` 筛选出来满足条件的item**
* **`distinct()` 对RDD中的item去重**
* **`sample()` 从RDD中的item中采样一部分出来,有放回或者无放回**
* **`sortBy()` 对RDD中的item进行排序**
看操作结果 用collect
"""
sc = SparkContext("local", 'map apply01')
numberRDD = sc.parallelize(range(1, 11))
print(numberRDD.collect())
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
map_RDD = numberRDD.map(lambda x: x ** 2)
print(map_RDD.collect())
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
filter_RDD = numberRDD.filter(lambda x: x >= 5)
print(filter_RDD.collect())
# [5, 6, 7, 8, 9, 10]
li = ["java", "java", "hadoop", "spark", "spark vs hadoop", "pyspark", "pyspark and spark"]
flatmap_RDD = sc.parallelize(li)
wordRDD = flatmap_RDD.flatMap(lambda x: x.split())
print(wordRDD.collect())
# ['java', 'java', 'hadoop', 'spark', 'spark', 'vs', 'hadoop', 'pyspark', 'pyspark', 'and', 'spark']
print(wordRDD.count())
# 11
distinct_RDD = flatmap_RDD.distinct()
print(distinct_RDD.collect())
# ['java', 'hadoop', 'spark', 'spark vs hadoop', 'pyspark', 'pyspark and spark']
# Transformation串联使用
def doubleodd(x):
if x % 2 == 1:
return 2 * x
return x
listRDD = sc.parallelize(range(1, 11))
resultRDD = (listRDD.map(doubleodd).filter(lambda x: x>6).distinct())
print(resultRDD.collect())
# [10, 14, 8, 18]
- actions
import findspark
findspark.init()
import os
import pyspark
from pyspark import SparkConf
from pyspark.context import SparkContext
"""
刚才提到了**惰性计算**,action,出现的时候才会真正计算
常见的action,当他们出现的时候,表明我们需要执行刚才定义的transform了:
* `collect()`: 计算所有的items并返回所有的结果到driver端,接着 `collect()`会以Python list的形式返回结果
* `first()`: 和上面是类似的,不过只返回第1个item
* `take(n)`: 类似,但是返回n个item
* `count()`: 计算RDD中item的个数
* `top(n)`: 返回头n个items,按照自然结果排序
* `reduce()`: 对RDD中的items做聚合
"""
sc = SparkContext('local', 'rdd_action')
numbersRDD1 = sc.parallelize(range(1, 11))
print(numbersRDD1.reduce(lambda x, y: x + y))
# 55
# 重复计算要开销 通过cache()的操作把它暂时保存在内存中
import numpy as np
li = np.linspace(1, 10, 10)
print(li)
# [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
numbersRDD = sc.parallelize(li)
squaresRDD = numbersRDD.map(lambda x: x ** 2)
# 后面的action 用两次 需要激活两次 开销大 采取办法:保存
squaresRDD.cache()
avg = squaresRDD.reduce(lambda x, y: x + y) / squaresRDD.count()
print(avg)
# 38.5
- 针对更复杂结构的transformations和actions
"""
针对更复杂结构的transformations和actions
除了`Spark`中最常见的transform和action,有更复杂的结构,比如非常非常经典的是以元组形式组织的k-v对(key, value)把它叫做**pair RDDs**,而Sark中针对这种item结构的数据,定义了一些transformation和action:
* `reduceByKey()`: 对所有有着相同key的items执行reduce操作
* `groupByKey()`: 返回类似(key, listOfValues)元组的RDD,后面的value List 是同一个key下面的
* `sortByKey()`: 按照key排序
* `countByKey()`: 按照key去对item个数进行统计
* `collectAsMap()`: 和collect有些类似,但是返回的是k-v的字典
"""
# 词频统计案列
rdd = sc.parallelize(["Hello hello", "Hello New York", "York says hello"])
resultRDD = (
rdd
.flatMap(lambda sentence: sentence.split(" ")) # split into words
.map(lambda word: word.lower()) # lowercase
.map(lambda word: (word, 1)) # count each appearance
.reduceByKey(lambda x, y: x + y) # add counts for each word
)
print(resultRDD.collect())
# [('hello', 3), ('world', 2), ('xiaoming', 2), ('say', 1)]
print(resultRDD.collectAsMap()) # 转成字典
# {'hello': 3, 'world': 2, 'xiaoming': 2, 'say': 1}
- spark DataFrame与Spark sql
Spark SQL 是 Spark 处理结构化数据的一个模块, 与基础的 Spark RDD API 不同, Spark SQL 提供了查询结构化数据及计算结果等信息的接口.在内部, Spark SQL 使用这个额外的信息去执行额外的优化.有几种方式可以跟 Spark SQL 进行交互, 包括 SQL 和 Dataset API.当使用相同执行引擎进行计算时, 无论使用哪种 API / 语言都可以快速的计算。
SQL
Spark SQL 的功能之一是执行 SQL 查询,Spark SQL 也能够被用于从已存在的 Hive 环境中读取数据。当以另外的编程语言运行SQL 时, 查询结果将以 Dataset/DataFrame的形式返回,也可以使用 命令行或者通过 JDBC/ODBC与 SQL 接口交互.
DataFrames
从RDD里可以生成类似大家在pandas中的DataFrame,同时可以方便地在上面完成各种操作。
构建SparkSession
Spark SQL中所有功能的入口点是 SparkSession 类. 要创建一个 SparkSession, 仅使用 SparkSession.builder()就可以了:
import findspark
findspark.init()
from pyspark.sql import SparkSession
spark = SparkSession \
.builder \
.appName("Python Spark SQL") \
.config("spark.some.config.option", "some-value") \
.getOrCreate()
### b.构建数据集与序列化
stringJSONRDD = spark.sparkContext.parallelize((
"""
{ "id": "123",
"name": "Katie",
"age": 19,
"eyeColor": "brown"
}""",
"""{
"id": "234",
"name": "Michael",
"age": 22,
"eyeColor": "green"
}""",
"""{
"id": "345",
"name": "Simone",
"age": 23,
"eyeColor": "blue"
}""")
)
# 构建DataFrame
dataJSON = spark.read.json(stringJSONRDD)
# 创建临时表
dataJSON.createOrReplaceTempView("dataJSON")
# DataFrame信息
dataJSON.show()
"""
+---+--------+---+-------+
|age|eyeColor| id| name|
+---+--------+---+-------+
| 19| brown|123| Katie|
| 22| green|234|Michael|
| 23| blue|345| Simone|
+---+--------+---+-------+
"""
spark.sql("select * from dataJSON").show()
"""
+---+--------+---+-------+
|age|eyeColor| id| name|
+---+--------+---+-------+
| 19| brown|123| Katie|
| 22| green|234|Michael|
| 23| blue|345| Simone|
+---+--------+---+-------+
"""
# 执行SQL请求
spark.sql("select * from dataJSON").collect() # show()
"""
+---+--------+---+-------+
|age|eyeColor| id| name|
+---+--------+---+-------+
| 19| brown|123| Katie|
| 22| green|234|Michael|
| 23| blue|345| Simone|
+---+--------+---+-------+
"""
# 输出数据表的格式
dataJSON.printSchema()
"""
root
|-- age: long (nullable = true)
|-- eyeColor: string (nullable = true)
|-- id: string (nullable = true)
|-- name: string (nullable = true)
"""
# 执行SQL
spark.sql("select count(1) from dataJSON").show()
"""
+--------+
|count(1)|
+--------+
| 3|
+--------+
"""
### c.DataFrame / SQL的写法
# DataFrame的写法
dataJSON.select("id", "age").filter("age = 22").show()
"""
+---+---+
| id|age|
+---+---+
|234| 22|
+---+---+
"""
# SQL的写法
spark.sql("select id, age from dataJSON where age = 22").show()
"""
+---+---+
| id|age|
+---+---+
|234| 22|
+---+---+
"""
# DataFrame的写法
dataJSON.select("name", "eyeColor").filter("eyeColor like 'b%'").show()
"""
+------+--------+
| name|eyeColor|
+------+--------+
| Katie| brown|
|Simone| blue|
+------+--------+
"""
# SQL的写法
spark.sql("select name, eyeColor from dataJSON where eyeColor like 'b%'").show()
"""
+------+--------+
| name|eyeColor|
+------+--------+
| Katie| brown|
|Simone| blue|
+------+--------+
"""