Spark核心数据结构RDD
RDD:Resilient Distributed Dataset,弹性分布式数据集
RDD是一个可分布式、可容错的数据集合
RDD提供了一种抽象的方式来处理大规模数据集
RDD可以在内存中进行高效的并行计算
RDD的特性
可分区性
可容错性
可读性
可恢复性
可优化性
RDD的创建
- parallelize:并行化一个已存在的集合
- textFile:读取外部文件系统
- wholeTextFiles:专门读取小文件的算子
RDD类型
a. HadoopRDD(从LocalFS或HDFS,加载的数据封装集合)
b. MapPartitionsRDD(调用map、filter、flatMap等函数产生的RDD)
c. ShuffleRDD(调用函数时,产生Shuffle时的RDD)
d. PythonRDD(使用python编程时,底层自动转换实现RDD)
RDD的分类
Tranformation算子:转换算子
都是lazy模式的,一般不会触发job的运行,返回值一定是RDD
Action算子:触发算子
一定会触发job的运行,返回值一定不是RDD
RDD中常用算子
转换算子
# 七个常用的转换算子的示例
1. map:对RDD中的每个元素应用一个函数,并返回一个新的RDD。
numbers = [1, 2, 3, 4, 5]
squared_numbers = sc.parallelize(numbers).map(lambda x: x**2)
# 输出结果:[1, 4, 9, 16, 25]
2. filter:根据给定的条件筛选出RDD中满足条件的元素,并返回一个新的RDD。
numbers = [1, 2, 3, 4, 5]
even_numbers = sc.parallelize(numbers).filter(lambda x: x % 2 == 0)
# 输出结果:[2, 4]
3. flatMap:对RDD中的每个元素应用一个函数,并返回一个扁平化的新RDD。
函数可以返回一个元素或一个元素的迭代器。
sentences = ["Hello world", "Spark is awesome"]
words = sc.parallelize(sentences).flatMap(lambda x: x.split(" "))
# 输出结果:['Hello', 'world', 'Spark', 'is', 'awesome']
4. distinct:去除RDD中的重复元素,并返回一个新的RDD。
numbers = [1, 2, 2, 3, 3, 3, 4, 5]
unique_numbers = sc.parallelize(numbers).distinct()
# 输出结果:[1, 2, 3, 4, 5]
5. sortBy:根据给定的排序键对RDD中的元素进行排序,并返回一个新的RDD。
numbers = [5, 2, 4, 1, 3]
sorted_numbers = sc.parallelize(numbers).sortBy(lambda x: x)
# 输出结果:[1, 2, 3, 4, 5]
6. groupByKey:按键对RDD中的元素进行分组,并返回一个键值对的RDD,
其中键是原始RDD中的唯一键,而值是具有相同键的元素组成的迭代器。
data = [("Alice", 1), ("Bob", 2), ("Alice", 3), ("Charlie", 4), ("Bob", 5)]
grouped_data = sc.parallelize(data).groupByKey()
# 输出结果:[('Alice', [1, 3]), ('Bob', [2, 5]), ('Charlie', [4])]
7. reduceByKey:对具有相同键的元素进行聚合操作,并返回一个新的键值对的RDD。
data = [("Alice", 1), ("Bob", 2), ("Alice", 3), ("Charlie", 4), ("Bob", 5)]
aggregated_data = sc.parallelize(data).reduceByKey(lambda x, y: x + y)
# 输出结果:[('Alice', 4), ('Bob', 7), ('Charlie', 4)]
触发算子
1.aggregate算子:使用指定的初始值和两个函数对RDD中的元素进行聚合操作。
rdd = sc.parallelize([1, 2, 3, 4, 5])
sum_of_squares = rdd.aggregate(0, lambda acc, x: acc + x**2,
lambda acc1, acc2: acc1 + acc2) # acc:累加器
print(sum_of_squares) # 输出: 55,即1^2 + 2^2 + 3^2 + 4^2 + 5^2 的和
2.collect算子:将RDD中的所有元素收集到驱动程序中,并返回一个包含所有元素的列表。
rdd = sc.parallelize([1, 2, 3, 4, 5])
result = rdd.collect()
print(result) # 输出: [1, 2, 3, 4, 5]
3.countByKey算子:对RDD中的每个键进行计数,并返回一个包含键和对应计数的字典。
rdd = sc.parallelize([(1, 'a'), (2, 'b'), (1, 'c'), (3, 'd'), (2, 'e')])
count_by_key = rdd.countByKey()
print(count_by_key) # 输出: {1: 2, 2: 2, 3: 1}
4.count算子:返回RDD中元素的数量
rdd = sc.parallelize([1, 2, 3, 4, 5])
count = rdd.count()
print(count) # 输出: 5
5.first算子:返回RDD中的第一个元素。
rdd = sc.parallelize([1, 2, 3, 4, 5])
first_element = rdd.first()
print(first_element) # 输出: 1
6.reduce算子:使用指定的二元函数对RDD中的元素进行聚合操作。
rdd = sc.parallelize([1, 2, 3, 4, 5])
sum_of_elements = rdd.reduce(lambda x, y: x + y)
print(sum_of_elements) # 输出: 15
7.saveAsTextFile算子:用于将RDD中的数据保存为文本文件。
它将RDD中的每个元素转换为字符串,并将其写入指定的路径下的文本文件中。
rdd = sc.parallelize([1, 2, 3, 4, 5])
rdd.saveAsTextFile("output.txt")
8.take算子:从RDD中获取前n个元素,并返回一个包含这些元素的列表。
用于快速查看RDD中的一部分数据.
rdd = sc.parallelize([1, 2, 3, 4, 5])
first_three_elements = rdd.take(3)
print(first_three_elements) # 输出: [1, 2, 3]
9.top算子:返回RDD中按指定顺序排列的前n个元素。
rdd = sc.parallelize([5, 3, 1, 4, 2])
top_elements = rdd.top(3)
print(top_elements) # 输出: [5, 4, 3]
综合案例
map案例
#1.需求
给下列国内电影票房排行榜Top10的吴京电影,拼接上"<吴京主演>"这个字符串。
#2.数据
长津湖,战狼2,流浪地球,长津湖之水门桥,流浪地球2
#3.实现
# map算子:一对一转换算子,有返回值
from pyspark import SparkContext
sc = SparkContext(appName="MySparkApp")
list1 = ['长津湖','战狼2','流浪地球','长津湖之水门桥','流浪地球2']
input_rdd = sc.parallelize(list1)
input_rdd.foreach(lambda x: print(x))
print("====================")
map_rdd = input_rdd.map(lambda x: x + "<吴京主演>")
map_rdd.foreach(lambda x: print(x))
# 输出
流浪地球
长津湖之水门桥
流浪地球2
长津湖
战狼2
====================
流浪地球<吴京主演>
长津湖之水门桥<吴京主演>
流浪地球2<吴京主演>
长津湖<吴京主演>
战狼2<吴京主演>
filter案例
#1.需求
对以下电影数据进行处理,并过滤掉美国电影
#2.数据
速度与激情10 美国 唐老大
阿凡达2水之道 美国 萨姆·沃辛顿
大话西游 中国香港 周星驰/朱茵
泰坦尼克号 美国 小李子
赌神 中国香港 周润发/王祖贤
肖胜克的救赎 美国 蒂姆·罗宾斯
湄公河行动 中国大陆 张涵予
忠犬八公的故事 美国 理查·基尔
满江红 中国大陆 沈腾
#3.代码
# filter算子,可以实现对数据的过滤操作
from pyspark import SparkContext
sc = SparkContext(appName="MySparkApp")
input_rdd = sc.textFile("/root/projects/算子/data/movie.txt")
filter_rdd = input_rdd.filter(lambda x: x.split(" ")[1] != "美国")
filter_rdd.foreach(lambda x: print(x))
# 输出
大话西游 中国香港 周星驰/朱茵
赌神 中国香港 周润发/王祖贤
湄公河行动 中国大陆 张涵予
满江红 中国大陆 沈腾
其余算子,以此类推