数据来源:
MovieLens数据集
MovieLens数据集包含多个用户对多部电影的评级数据,也包括电影元数据信息和用户属性信息。下载地址http://files.grouplens.org/datasets/movielens/
需求
1.查询用户平均分2.查询电影平均分
3.查询大于平均分的电影的数量
4.查询高分电影中(>3)打分次数最多的用户,并求出此人打的平均分5.查询每个用户的平均打分,最低打分,最高打分
6.查询被评分超过100次的电影,的平均分排名TOP10
代码
#coding:utf-8
from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StringType, IntegerType
import pandas as pd
from pyspark.sql import functions as F
if __name__ == '__main__':
spark=SparkSession.builder.appName("movie_demo").master("local[*]").getOrCreate()
sc=spark.sparkContext
#1.读取数据集
schema = StructType().add("user_id", StringType(), nullable=True). \
add("movie_id", IntegerType(), nullable=True). \
add("rank", IntegerType(), nullable=True). \
add("ts", StringType(), nullable=True)
df=spark.read.format("csv").option("sep","\t").option("header",False).option("encoding","utf-8").\
schema(schema=schema).load("../data/input/sql/u.data")
#需求一:用户平均分
df.groupBy("user_id").\
avg("rank").withColumnRenamed("avg(rank)","avg_rank").\
withColumn("avg_rank",F.round("avg_rank",2)).\
orderBy("avg_rank",ascending=False).show()
#需求二:电影平均分
df.createTempView('movie')
spark.sql("""
SELECT movie_id, ROUND(AVG(rank), 2) AS avg_rank FROM movie GROUP BY movie_id ORDER BY avg_rank DESC """).show()
#需求三:大于平均分的电影的数量
result=df.where(df['rank']>df.select(F.avg(df['rank'])).first()['avg(rank)']).count()
print("大于电影平均分的数量:",result)
#需求四:高分电影中(>3)打分次数最多的用户,此人打分的平均分
user_id=df.where("rank > 3").groupBy("user_id").count().orderBy("count",ascending=False).limit(1).first()['user_id']
df.filter(df['user_id']==user_id).select(F.round(F.avg("rank"),2)).show()
#需求五:每个用户的平均打分,最低打分,最高打分
df.groupBy("user_id").agg(
F.round(F.avg("rank"),2).alias("avg_rank"),
F.min("rank").alias("min_rank"),
F.max("rank").alias("max_rank")
).show()
#需求六:查询次数超过100次的电影平均分排名
df.groupBy("movie_id").agg(
F.count("movie_id").alias("cnt"),
F.round(F.avg("rank"),2).alias("avg_rank")
).where("cnt>100").orderBy("avg_rank",ascending=False).limit(10).show()
1. agg: 它是GroupedData对象的API, 作用是 在里面可以写多个聚合
2. alias: 它是Column对象的API, 可以针对一个列 进行改名
3. withColumnRenamed: 它是DataFrame的API, 可以对DF中的列进行改名, 一次改一个列, 改多个列 可以链式调用
4. orderBy: DataFrame的API, 进行排序, 参数1是被排序的列, 参数2是 升序(True) 或 降序 False
5. first: DataFrame的API, 取出DF的第一行数据, 返回值结果是Row对象.