Hadoop学习笔记(10)-Spqrk实现TopN(Python)

实验要求

获取蜀国武将中武力值最高的5位,即通过分布式计算框架实现从原始数据查询出武力最高的Top5。

数据准备

1 刘备 68 蜀国
2 马超 90 蜀国
3 黄忠 91 蜀国
4 魏延 76 蜀国
5 姜维 92 蜀国
6 关羽 96 蜀国
7 严颜 78 蜀国
8 孟达 64 蜀国
9 张飞 88 蜀国
10 马谡 76 蜀国
11 赵云 95 蜀国
12 法正 88 蜀国

将题目中所给的原始数据保存在本地的Desktop目录,并以文本文件的格式命名为forceData.txt。

预期结果

6 关羽 96 蜀国
11 赵云 95 蜀国
5 姜维 92 蜀国
3 黄忠 91 蜀国
2 马超 90 蜀国

相关类以及算子介绍

Python-Spark官网:http://spark.apache.org/docs/latest/api/python/pyspark.html

findspark

官方介绍: Provides findspark.init() to make pyspark importable as a regular library.

也就是为了让pyspark作为一个常规库导入提供了一个**findspark.init()**这样的一个工具。

pyspark:

pyspark是一个Python对Spark提供的API。

SparkContext:

SparkContext是spark功能的主要入口。其代表与spark集群的连接,能够用来在集群上创建RDD、累加器、广播变量。Spark功能的主要入口点。

parallelize(c, numSlices=None)

分发本地Python集合以形成RDD。如果输入表示性能范围,则建议使用xrange。

>>> sc.parallelize([0, 2, 3, 4, 6], 5).glom().collect()
[[0], [2], [3], [4], [6]]
>>> sc.parallelize(xrange(0, 6, 2), 5).glom().collect()
[[], [0], [], [2], [4]]
collect()

返回包含此RDD中所有元素的列表。

注意: 仅当预期结果数组较小时才应使用此方法,因为所有数据均已加载到驱动程序的内存中。

textFile(name, minPartitions=None, use_unicode=True)

从HDFS,本地文件系统(在所有节点上都可用)或任何Hadoop支持的文件系统URI中读取文本文件,并将其作为字符串的RDD返回。

如果use_unicode为False,则字符串将保持为str(编码为utf-8),这比unicode更快且更小。

path = os.path.join(tempdir, "sample-text.txt")
>>> with open(path, "w") as testFile:
...    _ = testFile.write("Hello world!")
>>> textFile = sc.textFile(path)
>>> textFile.collect()
['Hello world!']
map(f, preservesPartitioning=False)

通过将函数应用于此RDD的每个元素来返回新的RDD。

>>> rdd = sc.parallelize(["b", "a", "c"])
>>> sorted(rdd.map(lambda x: (x, 1)).collect())
[('a', 1), ('b', 1), ('c', 1)]
cache()

使用默认存储级别(MEMORY_ONLY)保留该RDD。

sortBy(keyfunc, ascending=True, numPartitions=None)

按给定的keyfunc排序此RDD。

>>> tmp = [('a', 1), ('b', 2), ('1', 3), ('d', 4), ('2', 5)]
>>> sc.parallelize(tmp).sortBy(lambda x: x[0]).collect()
[('1', 3), ('2', 5), ('a', 1), ('b', 2), ('d', 4)]
>>> sc.parallelize(tmp).sortBy(lambda x: x[1]).collect()
[('a', 1), ('b', 2), ('1', 3), ('d', 4), ('2', 5)]
take(num)

取RDD的前num个元素。

它的工作方式是先扫描一个分区,然后使用该分区的结果来估算满足限制所需的其他分区的数量。

注意: 仅当预期结果数组较小时才应使用此方法,因为所有数据均已加载到驱动程序的内存中。

sc.parallelize([2, 3, 4, 5, 6]).cache().take(2)
[2, 3]
>>> sc.parallelize([2, 3, 4, 5, 6]).take(10)
[2, 3, 4, 5, 6]
>>> sc.parallelize(range(100), 100).filter(lambda x: x > 90).take(3)
[91, 92, 93]

实现TopN不同方案

实现方案一

思路分析:

  1. 将数据按照自定义函数格式读入,并利用map算子使用该函数来返回新的RDD。
  2. 利用collect()返回包含此RDD中所有元素的列表。
  3. sortBy()按给定的keyfunc排序此RDD。(本题就是按照武力值指标进行排序,并利用False选项指定由高到低排序)
  4. 利用take()算子取RDD的前num个元素。(本题是需要top5的操作)

实现完整代码:

import findspark
findspark.init("/usr/local/spark") # 指明SPARK_HOME目录
from pyspark import SparkContext  
sc.stop()
sc=SparkContext(appName='forceLevel')
def map_func(x):#自定义函数来正确读入数据
    s = x.split()
    return (s[0],s[1],s[2],s[3])
lines=sc.textFile("file:/home/hadoop/Desktop/forceData.txt").map(lambda x:map_func(x)).cache()#导入数据且保持在内存中,其中cache():数据保持在内存中
tmp=sc.parallelize(lines.collect()).sortBy(lambda x: x[2],False).collect()#按照武力值指标进行排序,并利用False选项指定由高到低排序
sc.parallelize(tmp).cache().take(5)#利用take()算子取RDD的前5个元素

实验结果:

实现方案二

思路分析:

  1. 将数据按照自定义函数格式读入,并利用map算子使用该函数来返回新的RDD。
  2. 利用collect()返回包含此RDD中所有元素的列表。
  3. 利用top算子取RDD的前num个元素。(因为top算子返回以降序排列的列表)
import findspark
findspark.init("/usr/local/spark") # 指明SPARK_HOME目录
from pyspark import SparkContext  
sc.stop()
sc=SparkContext(appName='forceLevel')
def map_func(x):#自定义函数来正确读入数据
    s = x.split()
    return (s[0],s[1],s[2],s[3])
lines=sc.textFile("file:/home/hadoop/Desktop/forceData.txt").map(lambda x:map_func(x)).cache()#导入数据且保持在内存中,其中cache():数据保持在内存中
tmp=sc.parallelize(lines.collect(),2).top(5,key=lambda x: x[2])#利用top算子取RDD的前num个元素。(因为top算子返回以降序排列的列表)
print(tmp)

实验结果:

实现方案三

思路分析:

实现完整代码:

  1. 将数据按照自定义函数格式读入,并利用map算子使用该函数来返回新的RDD。
  2. 利用collect()返回包含此RDD中所有元素的列表。
  3. 利用sortByKey算子对以武力值作为key的rdd进行排序。
  4. 利用map算子返回目标格式要求的列表,并且利用take算子取前5项实现TopN。
import findspark
findspark.init("/usr/local/spark") # 指明SPARK_HOME
from pyspark import SparkContext  
sc.stop()
def map_func(x):#自定义函数来正确读入数据
    s = x.split()
    return (s[2], [s[0],s[1],s[3]])#返回为(key,vaklue)格式,其中key:x[0],value:x[1]且为有三个元素的列表,其中武力值作为key,后面利用key排序

def map_func1(x):#返回为最终想要的格式列表
    return (x[1][0],x[1][1],x[0],x[1][2])

sc=SparkContext(appName='Students') 
lines=sc.textFile("file:/home/hadoop/Desktop/forceData.txt").map(lambda x:map_func(x)).cache() #导入数据且保持在内存中,其中cache():数据保持在内存中
tmp=sc.parallelize(lines.collect()).sortByKey(keyfunc=lambda x: -int(x)).collect()#利用sortByKey算子对以武力值作为key的rdd进行排序。
rdd=sc.parallelize(tmp)
rdd.map(lambda x:map_func1(x)).take(5)#返回目标格式要求的列表,并且取前5项

实验结果:

以上就是本次给大家分享的Hadoop学习笔记-利用Python结合Spqrk实现TopN的具体思路以及用到的Spark算子都给大家作了详细的介绍,希望对各位小伙伴有用哇,这次写这个东西突然感觉开发文档还真是个好东西,以后得多培养培养这方面的能力啦。要是有什么问题欢迎留言哟,觉得对你有用的话就赞一赞吧,你的支持就是小编前进的动力啦!

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值