问题:
编写独立应用程序实现求平均值问题 每个输入文件表示班级学生某个学科的成绩,每行内容由两个字段组成,第一个是学生名字,第二个是学生的成绩;编写Spark独立应用程序求出所有学生的平均成绩,并输出到一个新文件中。下面是输入文件和输出文件的一个样例,供参考。
Algorithm成绩:
小明 92
小红 87
小新 82
小丽 90
Database成绩:
小明 95
小红 81
小新 89
小丽 85
Python成绩:
小明 82
小红 83
小新 94
小丽 91
平均成绩如下:
(小红,83.67)
(小新,88.33)
(小明,89.67)
(小丽,88.67)
编程思路:
- 把三个文件分别读取,然后整合成一个文件,最终格式:姓名 成绩 学科
- 按照scala代码的思路,统计每个人的平均成绩即可
pyspark实现:
# 读入数据
str_path = '../测试数据/spark/课程数据/'
course_list = [
'Algorithm',
'DataBase',
'python',
]
rdd_data = []
for course in course_list:
path = str_path + course + '.txt'
print(path)
rdd = sc.textFile(path)
rdd_data.append(rdd)
print(rdd_data)
# 把所有rdd合并成一个
rdd_total = rdd_data[0]
for i in range(1, len(rdd_data)):
rdd_total = rdd_total.union(rdd_data[i])
print('所有数据:')
print(rdd_total.collect())
# 求每个人的平均值
stu_1 = rdd_total.map(lambda x: (x.split(" ")[0], (float(x.split(" ")[1]), 1)))
print(stu_1.collect())
stu_2 = stu_1.reduceByKey(lambda x, y: (x[0]+y[0], x[1]+y[1]))
print(stu_2.collect())
stu_3 = stu_2.mapValues(lambda x: x[0]/x[1])
# 或者用这么计算也可以
stu_4 = stu_2.map(lambda x: (x[0], x[1][0]/x[1][1]))
print(stu_3.collect())
# print(stu_4.collect())
输出:
../测试数据/spark/课程数据/Algorithm.txt
../测试数据/spark/课程数据/DataBase.txt
../测试数据/spark/课程数据/python.txt
[../测试数据/spark/课程数据/Algorithm.txt MapPartitionsRDD[23] at textFile at <unknown>:0, ../测试数据/spark/课程数据/DataBase.txt MapPartitionsRDD[25] at textFile at <unknown>:0, ../测试数据/spark/课程数据/python.txt MapPartitionsRDD[27] at textFile at <unknown>:0]
所有数据:
['小明 92', '小红 87', '小新 82', '小丽 90', '小明 95', '小红 81', '小新 89', '小丽 85', '小明 82', '小红 83', '小新 94', '小丽 91']
[('小明', (92.0, 1)), ('小红', (87.0, 1)), ('小新', (82.0, 1)), ('小丽', (90.0, 1)), ('小明', (95.0, 1)), ('小红', (81.0, 1)), ('小新', (89.0, 1)), ('小丽', (85.0, 1)), ('小明', (82.0, 1)), ('小红', (83.0, 1)), ('小新', (94.0, 1)), ('小丽', (91.0, 1))]
[('小新', (265.0, 3)), ('小丽', (266.0, 3)), ('小红', (251.0, 3)), ('小明', (269.0, 3))]
[('小新', 88.33333333333333), ('小丽', 88.66666666666667), ('小红', 83.66666666666667), ('小明', 89.66666666666667)]