Pyspark学习笔记

Pyspark学习笔记1——Transformation算子

Transformation算子

构建sparkConf对象

from pyspark import SparkConf, SparkContext
# 构建sparkConf对象
conf = SparkConf().setAppName("WordCount").setMaster("local")
sc = SparkContext(conf=conf)  # 构建SparkContext执行环境入口
inputFile = "../data/word.txt"
textFile = sc.textFile(inputFile)
wordCount = textFile.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b)
wordCount.foreach(print)

RDD创建:并行化创建

# RDD创建:并行化创建
# 并行化创建,将本地集合->转化为分布式RDD
# 构建Spark执行环境
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)

# sc对象的parallellize方法,可以将本地集合转化成RDD返回
# rdd = SparkContext.parallelize(参数1,参数2)
# 参数1:集合对象; 参数2:分区数
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
rdd = sc.parallelize(data, numSlices=3)
print(rdd.collect())
print(rdd.getNumPartitions())  # 获取RDD分区数量

RDD读取文件创建

# RDD读取文件创建
# 构建Spark执行环境
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
input_file = "../data/words.txt"
# # SparkContext.textFile(参数1, 参数2)
# # 参数1:文件路径,支持本地文件、HDFS
# # 参数2:表示最小分区数量,在spark允许范围内,参数2有效,在允许范围外,参数无效,
# # 除非有很明确的指向性,一般不设置分区
rdd = sc.textFile(input_file, 1000)  # 分配了1000个分区,但实际上只分配了27个分区
print(rdd.getNumPartitions())  # 获取RDD分区数量
print(rdd.collect())

API读取大量小文件

# API读取大量小文件
# SparkContext.wholeTextFiles(参数1, 参数2)
# 参数1:文件路径,支持本地文件、HDFS
# 参数2:表示最小分区数量,最多只能开到文件数量
# 这个API偏向于少量分区读取数据,文件的数据量少、分区多,导致shuffle的几率更高,所以尽量少分区读取数据

conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
input_file = "../data/tiny_files"
rdd = sc.wholeTextFiles(input_file, 1000)  # 分配了1000个分区,但实际上只分配了27个分区
print(rdd.getNumPartitions())  # 获取RDD分区数量
print(rdd.collect())

RDD算子分类:Transformation转化算子,Action:动作行动算子
Transformation转化算子,返回值仍旧是RDD,没有action算子时不工作
action算子:返回值不是RDD

map算子—Transformation

# map算子
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5])


def map_func(data):
    return data * 10


print(rdd.map(map_func).collect())

print(rdd.map(lambda data: data * 10).collect())

flatMap算子—Transformation

# flatMap算子
# 功能:对rdd执行map操作,然后进行接触嵌套操作
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.parallelize(['a b c', 'a c e ', 'e c a'])
# 按照空格切割数据后,解除嵌套
print(rdd.map(lambda x: x.split(' ')).collect())  # 输出:[['a', 'b', 'c'], ['a', 'c', 'e', ''], ['e', 'c', 'a']]
print(rdd.flatMap(lambda x: x.split(' ')).collect())  # 输出:['a', 'b', 'c', 'a', 'c', 'e', '', 'e', 'c', 'a']

reduceByKey算子—Transformation

# reduceByKey算子—Transformation
# 功能:针对KVRDD,自动按照key分组,然后根据提供的聚合路基,完成组内数据(value)的聚合操作
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 1), ('b', 1), ('b', 1), ('c', 1)])
result = rdd.reduceByKey(lambda a, b: a + b)
print(result.collect())

groupBy算子—Transformation

# groupBy算子—Transformation,RDD的数据进行分组
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5])
# 分组,将数字分层,偶数和奇数2个组
rdd2 = rdd.groupBy(lambda num: 'even' if (num % 2 == 0) else 'odd')
# 将rdd2的元素value转化成list,这样print可以输出内容
print(rdd2.map(lambda x: (x[0], list(x[1]))).collect())
# 输出结果  [('odd', [1, 3, 5]), ('even', [2, 4])]

Filter算子—Transformation

# Filter算子—Transformation,过滤想要的数据进行保留
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5])
# 保留奇数
print(rdd.filter(lambda x: x % 2 == 1).collect())

distinct算子—Transformation

# distinct算子—Transformation,RDD数据进行驱虫,RDD
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 1, 3, 3, 5, 5, 6, 6, 9, 9])
# 按照空格切分数据后,解除嵌套
print(rdd.distinct().collect())  # [1, 3, 5, 6, 9]

union算子—Transformation

# union算子—Transformation,2个rdd合并成1个rdd返回
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd1 = sc.parallelize([1, 1, 3, 3])
rdd2 = sc.parallelize(['a', 'b', 'c'])
union_rdd = rdd1.union(rdd2)
print(union_rdd.collect())  # [1, 1, 3, 3, 'a', 'b', 'c']

join算子—Transformation

# join算子—Transformation,对两个RDD执行JOIN操作(可实现SQL的内\外连接)
# rdd.join(other_rdd)  # 内连接
# rdd.leftOuterJoin(other_rdd)  # 左外
# rdd.rightOtherJoin(other_rdd)  # 右外

conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
# 部门ID和员工姓名
x = sc.parallelize([(1001, 'zhangsan'), (1002, 'lisi'), (1003, 'wangwu'), (1004, 'zhangliu')])
# 部门ID和部门名称
y = sc.parallelize([(1001, 'sales'), (1002, 'tech')])
# join是内连接
print(x.join(y).collect())  # [(1002, ('lisi', 'tech')), (1001, ('zhangsan', 'sales'))]
# leftOuterJoin
print(x.leftOuterJoin(y).collect())
# [(1002, ('lisi', 'tech')), (1004, ('zhangliu', None)), (1001, ('zhangsan', 'sales')), (1003, ('wangwu', None))]

intersection算子—Transformation

# intersection算子—Transformation,求两个rdd的交集,返回一个新的rdd
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd1 = sc.parallelize([('a', 1), ('b', 1)])
rdd2 = sc.parallelize([('a', 1), ('c', 1)])
union_rdd = rdd1.intersection(rdd2)
print(union_rdd.collect())
# 结果:[('a', 1)]

groupByKey算子—Transformation

# glom算子,将RDD的数据,加上嵌套,嵌套按照分区来进行
# groupByKey算子,针对KVRDD,自动按照Key分组
conf = SparkConf().setAppName("create rdd").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 1), ('b', 1), ('b', 1), ('b', 1)])
grouped_rdd = rdd.groupByKey()
# print(grouped_rdd.collect()) 
# [('a', <pyspark.resultiterable.ResultIterable object at 0x000001EED3542FD0>), ('b', <pyspark.resultiterable.ResultIterable object at 0x000001EED35941D0>)]
print(grouped_rdd.map(lambda x: (x[0], list(x[1]))).collect())
# 结果:[('a', [1, 1]), ('b', [1, 1, 1])]

sortBy算子—Transformation

# sortBy算子—Transformation。对RDD数据进行排序,基于指定的排序依据
# sortByKey算子—Transformation。对RDD数据进行排序,按照key排序
# sc.sortByKey(ascending=True, numPartitions=None, keyfunc)
# ascending=True 升序,False降序,默认升序
# numPartitions:按照几个分区进行排序,如果全局有序,设置1
# keyfunc:在排序前对Key进行处理
conf = SparkConf().setAppName("WordCount").setMaster("local")
sc = SparkContext(conf=conf)  # 构建SparkContext执行环境入口
rdd = sc.parallelize([('a', 1), ('E', 1), ('c', 1), ('B', 1), ('n', 1), ('p', 1),
                      ('K', 1), ('L', 1), ('i', 1), ('y', 1), ('Q', 1),
                      ('A', 1), ('r', 1), ('W', 1), ('V', 1), ('S', 1)], 3)
print(rdd.sortByKey().collect())   # 默认按照key进行升序排序
# 结果:[('A', 1), ('B', 1), ('E', 1), ('K', 1), ('L', 1), ('Q', 1), ('S', 1), ('V', 1), ('W', 1), ('a', 1), ('c', 1), ('i', 1), ('n', 1), ('p', 1), ('r', 1), ('y', 1)]

# 如果要确保全局有序,排序分区数要给1,不是1只能保证各个分区内排好序,整体上不保证
print(rdd.sortByKey(ascending=False, numPartitions=5).collect())
# 结果:[('y', 1), ('r', 1), ('p', 1), ('n', 1), ('i', 1), ('c', 1), ('a', 1), ('W', 1), ('V', 1), ('S', 1), ('Q', 1), ('L', 1), ('K', 1), ('E', 1), ('B', 1), ('A', 1)]
print(rdd.sortByKey(ascending=False, numPartitions=5).glom().collect())
# 输出分区排序结果:[[('y', 1), ('r', 1), ('p', 1)], [('n', 1), ('i', 1), ('c', 1)], [('a', 1), ('W', 1), ('V', 1)], [('S', 1), ('Q', 1), ('L', 1)], [('K', 1), ('E', 1), ('B', 1), ('A', 1)]]

# 对排序的key进行处理,按字母表顺序对列表字符串进行排序,对大小写不敏感
print(rdd.sortByKey(ascending=True, numPartitions=1, keyfunc=lambda key: str(key).lower()).collect())
# 结果:[('a', 1), ('A', 1), ('B', 1), ('c', 1), ('E', 1), ('i', 1), ('K', 1), ('L', 1), ('n', 1), ('p', 1), ('Q', 1), ('r', 1), ('S', 1), ('V', 1), ('W', 1), ('y', 1)]

Transformation案例

1

# 需求:读取data文件中的order.txt文件,提取北京的数据,组合北京和商品类别进行输出
# 同时对数据结果集合进行去重,得到北京收卖的商品类别信息

conf = SparkConf().setAppName("WordCount").setMaster("local")
sc = SparkContext(conf=conf)  # 构建SparkContext执行环境入口
# 读取数据
input_file = "../data/order.text"
rdd = sc.textFile(input_file)
# 将每条json数据取出
json_str_rdd = rdd.flatMap(lambda x: x.split("|"))
# 将每个json字符串变成字典对象
json_dict_rdd = json_str_rdd.map(lambda x: json.loads(x))
# 过滤数据,只保留北京
beijing_rdd = json_dict_rdd.filter(lambda x: x['areaName'] == '北京')
# 组合北京和商品类型
result_rdd = beijing_rdd.map(lambda x: x['areaName'] + '-' + x['category'])
print(result_rdd.collect())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值