旅游推荐系统(getEchartsData.py)

getEchartsData.py

python 复制代码
from app.utils import getPublicData
# 从 app 应用的 utils 包中导入 getPublicData 模块
# getPublicData 是一个公共数据模块,提供了获取景点数据、用户数据等函数

import datetime
# 导入 Python 的 datetime 模块,用于处理日期和时间
# 这里主要用于将日期字符串转换为时间戳进行排序

travelInfoList = getPublicData.getAllTravelInfoMapData()
# 调用 getPublicData 模块中的 getAllTravelInfoMapData 函数
# 获取所有景点的完整数据,返回经过处理的景点对象列表
# 这个列表在全局范围内加载,供本模块的所有函数使用,避免重复查询数据库

# ============================================================================
# 城市和景点等级分析相关函数
# ============================================================================

def cityCharDataOne():
    # 定义获取城市分布数据(按省份统计)的函数
    # 用于生成柱状图或饼图,展示各省份的景点数量
    
    cityDic = {}
    # 初始化一个空字典,用于统计各省份的景点数量
    # 键是省份名称,值是该省份的景点数量
    
    for travel in travelInfoList:
        # 遍历所有景点对象
        
        if cityDic.get(travel.province, -1) == -1:
            # 检查当前景点所在的省份是否已经在字典中
            # dict.get(key, default) 方法:如果键存在返回对应的值,否则返回默认值 -1
            # 如果返回 -1,说明这个省份还没有被记录过
            
            cityDic[travel.province] = 1
            # 将这个省份加入字典,并设置数量为 1
        else:
            cityDic[travel.province] += 1
            # 如果省份已经存在,将其对应的数量加 1
    
    return list(cityDic.keys()), list(cityDic.values())
    # 返回两个列表:
    #   keys():省份名称列表,如 ['北京', '上海', '广东', ...]
    #   values():对应的景点数量列表,如 [15, 8, 23, ...]
    # 这种格式适合前端图表库(如 ECharts)直接使用

def cityCharDataTwo():
    # 定义获取城市分布数据(按景点等级统计)的函数
    # 用于展示不同等级景区(5A、4A等)的数量分布
    
    cityDic = {}
    # 初始化空字典,用于统计各等级景点的数量
    # 键是景点等级(如 '5A景区', '4A景区', '未评级'),值是该等级的数量
    
    for travel in travelInfoList:
        # 遍历所有景点对象
        
        if cityDic.get(travel.level, -1) == -1:
            # 检查当前景点的等级是否已经在字典中
            
            cityDic[travel.level] = 1
            # 如果不存在,加入字典并计数为 1
        else:
            cityDic[travel.level] += 1
            # 如果已存在,计数加 1
    
    resultData = []
    # 初始化结果列表
    
    for key, value in cityDic.items():
        # 遍历统计好的字典
        # key 是等级名称,value 是该等级的景点数量
        
        resultData.append({
            'name': key,
            'value': value
        })
        # 转换成 {name: '5A景区', value: 25} 的格式
        # 这种格式适合前端图表库的饼图、环形图等
    
    return resultData
    # 返回处理后的数据

# ============================================================================
# 评分情况分析相关函数
# ============================================================================

def getRateCharDataOne(travelList):
    # 定义获取评分分布数据(按星级统计)的函数
    # 参数 travelList 是景点对象列表(可能是筛选后的)
    # 统计各星级(如 45星、40星等)的景点数量
    
    startDic = {}
    # 初始化空字典,注意变量名拼写:startDic 应该是 starDic(星级字典)
    
    for travel in travelList:
        # 遍历传入的景点列表
        
        if startDic.get(travel.star, -1) == -1:
            # 检查当前景点的星级是否已经在字典中
            # travel.star 是星级评分,如 45 表示 4.5星
            
            startDic[travel.star] = 1
            # 如果不存在,加入字典并计数为 1
        else:
            startDic[travel.star] += 1
            # 如果已存在,计数加 1
    
    resultData = []
    # 初始化结果列表
    
    for key, value in startDic.items():
        # 遍历统计好的字典
        
        resultData.append({
            'name': key,
            'value': value
        })
        # 转换成 {name: '45', value: 12} 的格式
    
    return resultData
    # 返回星级分布数据

def getRateCharDataTwo(travelList):
    # 定义获取评分分布数据(按具体分数统计)的函数
    # 参数 travelList 是景点对象列表
    # 统计各分数(如 5.0、4.5、4.0等)的景点数量
    
    startDic = {}
    # 初始化空字典(同样有拼写问题,应该是 starDic)
    
    for travel in travelList:
        # 遍历所有景点
        
        if startDic.get(travel.score, -1) == -1:
            # 检查当前景点的分数是否已经在字典中
            # travel.score 是具体分数,如 '5.0'、'4.5' 等
            
            startDic[travel.score] = 1
            # 如果不存在,加入字典并计数为 1
        else:
            startDic[travel.score] += 1
            # 如果已存在,计数加 1
    
    resultData = []
    # 初始化结果列表
    
    for key, value in startDic.items():
        # 遍历统计好的字典
        
        resultData.append({
            'name': key,
            'value': value
        })
        # 转换成 {name: '5.0', value: 8} 的格式
    
    return resultData
    # 返回分数分布数据

# ============================================================================
# 价格销量分析相关函数
# ============================================================================

def getPriceCharDataOne(traveList):
    # 定义获取价格分布数据的函数
    # 函数注释:景点价格趋势分析
    # 将景点按价格区间分组统计
    
    xData = ['免费', '100元以内', '200元以内', '300元以内', '400元以内', '500元以内', '500元以外']
    # 定义价格区间的标签列表
    # 注意:第一个区间是'免费',但后面判断用的是 price <= 10,逻辑上应该是价格<=10元的视为免费
    
    yData = [0 for x in range(len(xData))]
    # 初始化一个与 xData 长度相同的零列表,用于存储各价格区间的景点数量
    # 列表推导式生成 [0, 0, 0, 0, 0, 0, 0]
    
    for travel in traveList:
        # 遍历所有景点
        
        price = float(travel.price)
        # 将景点的价格字段(字符串)转换为浮点数
        # 因为价格可能包含小数,所以使用 float()
        
        if price <= 10:
            # 如果价格小于等于 10 元,视为免费
            # 这里逻辑可能有问题:免费应该是 price == 0,但有些景点可能只收几元管理费
            yData[0] += 1
            # 第一个区间(免费)计数加 1
        
        elif price <= 100:
            # 如果价格在 10-100 元之间(包含100)
            yData[1] += 1
            # 第二个区间(100元以内)计数加 1
        
        elif price <= 200:
            # 如果价格在 100-200 元之间
            yData[2] += 1
        
        elif price <= 300:
            # 如果价格在 200-300 元之间
            yData[3] += 1
        
        elif price <= 400:
            # 如果价格在 300-400 元之间
            yData[4] += 1
        
        elif price <= 500:
            # 如果价格在 400-500 元之间
            yData[5] += 1
        
        elif price > 500:
            # 如果价格大于 500 元
            yData[6] += 1
    
    return xData, yData
    # 返回两个列表:价格区间标签和对应的景点数量

def getPriceCharDataTwo(traveList):
    # 定义获取销量分布数据的函数
    # 函数注释:景点销量分析
    # 将景点按销量区间分组统计
    
    xData = [str(x * 300) + '份以内' for x in range(1, 15)]
    # 生成销量区间标签
    # 列表推导式:x 从 1 到 14,生成标签如:
    # '300份以内', '600份以内', '900份以内', ... '4200份以内'
    
    yData = [0 for x in range(len(xData))]
    # 初始化一个与 xData 长度相同的零列表,用于存储各销量区间的景点数量
    
    for travel in traveList:
        # 遍历所有景点
        
        saleCount = float(travel.saleCount)
        # 将景点的销量字段(字符串)转换为浮点数
        
        for x in range(1, 15):
            # 循环遍历 1 到 14
            
            count = x * 300
            # 计算当前区间的上限,如 300、600、900...
            
            if saleCount <= count:
                # 如果当前景点的销量小于等于当前区间上限
                
                yData[x - 1] += 1
                # 对应区间计数加 1
                # 因为列表索引从 0 开始,而 x 从 1 开始,所以用 x-1
                
                break
                # 找到所属区间后跳出内层循环,避免重复计数
    
    return xData, yData
    # 返回销量区间标签和对应的景点数量

def getPriceCharDataThree(travelList):
    # 定义获取折扣分布数据的函数
    # 统计各种折扣类型的景点数量
    
    startDic = {}
    # 初始化空字典(变量名 startDic 应该是 discountDic)
    
    for travel in travelList:
        # 遍历所有景点
        
        if startDic.get(travel.discount, -1) == -1:
            # 检查当前景点的折扣类型是否已经在字典中
            # travel.discount 是折扣信息,如 '8折'、'学生票半价' 等
            
            startDic[travel.discount] = 1
            # 如果不存在,加入字典并计数为 1
        else:
            startDic[travel.discount] += 1
            # 如果已存在,计数加 1
    
    resultData = []
    # 初始化结果列表
    
    for key, value in startDic.items():
        # 遍历统计好的字典
        
        resultData.append({
            'name': key,
            'value': value
        })
        # 转换成 {name: '8折', value: 15} 的格式
    
    return resultData
    # 返回折扣分布数据

# ============================================================================
# 评论分析相关函数
# ============================================================================

def getCommentsCharDataOne():
    # 定义获取评论时间分布数据的函数
    # 统计每天有多少条评论,用于展示评论的时间趋势
    
    commentsList = getPublicData.getAllCommentsData()
    # 调用公共模块中的函数,获取所有景点的所有评论
    # 返回一个包含所有评论的列表,每个评论是一个字典
    
    xData = []
    # 初始化 xData 列表,用于存储评论日期
    
    def get_list(date):
        # 定义一个内部辅助函数,用于将日期字符串转换为时间戳
        # 参数 date 是日期字符串,格式如 '2024-03-19'
        
        return datetime.datetime.strptime(date, '%Y-%m-%d').timestamp()
        # datetime.strptime() 将字符串解析为 datetime 对象
        # 指定格式 '%Y-%m-%d' 表示年-月-日
        # timestamp() 将 datetime 对象转换为 Unix 时间戳(浮点数)
        # 时间戳可以方便地进行日期比较和排序
    
    for comment in commentsList:
        # 遍历所有评论
        
        xData.append(comment['date'])
        # 将每条评论的日期添加到 xData 列表
    
    xData = list(set(xData))
    # set() 将列表转换为集合,自动去重
    # 因为很多评论可能是同一天的,这里只保留唯一的日期
    
    xData = list(sorted(xData, key=lambda x: get_list(x), reverse=True))
    # sorted() 对 xData 进行排序
    # key=lambda x: get_list(x) 指定按日期的时间戳排序
    # reverse=True 表示降序排列,最新的日期在前
    
    yData = [0 for x in range(len(xData))]
    # 初始化与 xData 长度相同的零列表,用于存储每天的评论数量
    
    for comment in commentsList:
        # 再次遍历所有评论
        
        for index, date in enumerate(xData):
            # 遍历已排序的唯一日期列表
            # enumerate 同时获取索引(index)和日期值(date)
            
            if comment['date'] == date:
                # 如果当前评论的日期等于当前遍历到的日期
                
                yData[index] += 1
                # 对应日期的评论计数加 1
    
    return xData, yData
    # 返回两个列表:日期列表和对应的评论数量列表

def getCommentsCharDataTwo():
    # 定义获取评论评分分布数据的函数
    # 统计不同评分(1-5分)的评论数量
    
    commentsList = getPublicData.getAllCommentsData()
    # 获取所有评论列表
    
    startDic = {}
    # 初始化空字典(变量名应该是 scoreDic)
    
    for travel in commentsList:
        # 遍历所有评论
        # 注意变量名 travel 实际是 comment,容易引起误解
        
        if startDic.get(travel['score'], -1) == -1:
            # 检查当前评论的评分是否已经在字典中
            # travel['score'] 是这条评论的评分
            
            startDic[travel['score']] = 1
            # 如果不存在,加入字典并计数为 1
        else:
            startDic[travel['score']] += 1
            # 如果已存在,计数加 1
    
    resultData = []
    # 初始化结果列表
    
    for key, value in startDic.items():
        # 遍历统计好的字典
        
        resultData.append({
            'name': key,
            'value': value
        })
        # 转换成 {name: '5', value: 128} 的格式
    
    return resultData
    # 返回评论评分分布数据

def getCommentsCharDataThree():
    # 定义获取评论数量分布数据的函数
    # 统计景点按评论数量分组的分布情况
    
    travelList = getPublicData.getAllTravelInfoMapData()
    # 获取所有景点列表
    
    xData = [str(x * 1000) + '条以内' for x in range(1, 20)]
    # 生成评论数量区间标签
    # x 从 1 到 19,生成标签如:
    # '1000条以内', '2000条以内', '3000条以内', ... '19000条以内'
    
    yData = [0 for x in range(len(xData))]
    # 初始化与 xData 长度相同的零列表,用于存储各区间的景点数量
    
    for travel in travelList:
        # 遍历所有景点
        
        saleCount = int(travel.commentsLen)
        # 将景点的评论数字段(字符串)转换为整数
        
        for x in range(1, 20):
            # 循环遍历 1 到 19
            
            count = x * 1000
            # 计算当前区间的上限,如 1000、2000、3000...
            
            if saleCount <= count:
                # 如果当前景点的评论数小于等于当前区间上限
                
                yData[x - 1] += 1
                # 对应区间计数加 1
                
                break
                # 找到所属区间后跳出内层循环
    
    return xData, yData
    # 返回评论数量区间标签和对应的景点数量

函数功能总结

函数 功能 返回数据
cityCharDataOne 统计各省份景点数量 省份列表、对应数量列表
cityCharDataTwo 统计各等级景点数量 等级分布字典列表
getRateCharDataOne 统计各星级景点数量 星级分布字典列表
getRateCharDataTwo 统计各分数景点数量 分数分布字典列表
getPriceCharDataOne 价格区间分布统计 价格区间标签、对应数量
getPriceCharDataTwo 销量区间分布统计 销量区间标签、对应数量
getPriceCharDataThree 折扣类型分布统计 折扣分布字典列表
getCommentsCharDataOne 评论时间趋势统计 日期列表、对应评论数量
getCommentsCharDataTwo 评论评分分布统计 评分分布字典列表
getCommentsCharDataThree 景点评论数量分布 评论数区间标签、对应数量

这个模块是数据可视化的核心,负责将原始数据加工成各种图表所需的格式,为前端图表展示提供数据支持。

相关推荐
宸津-代码粉碎机1 小时前
SpringBoot 任务执行链路追踪实战:TraceID 透传全解析,实现从调度到执行的全链路可观测
开发语言·人工智能·spring boot·后端·python
veminhe2 小时前
Python编写isprime() 函数,参数为整数,要有异常处理。函数功能是如果整数是质数,返回True ,否则返回False。
python
Bert.Cai2 小时前
Python flush函数作用
开发语言·python
计算机徐师兄2 小时前
Python基于Django的高校档案安全管理系统(附源码,文档说明)
python·django·高校档案安全管理系统·python高校档案安全管理·python高校档案管理系统·高校档案·高校档案管理系统
云青黛2 小时前
ReAct(推理与行动)框架
python·算法
二闹2 小时前
Python中@classmethod和@staticmethod的真正区别懂了吗?
后端·python
布局呆星2 小时前
Python 文件操作教程
开发语言·python
昨夜见军贴06162 小时前
旅游客车环境检测中的AI审核与IACheck:让空气质量报告更规范、更可信
人工智能·旅游
傻啦嘿哟2 小时前
Python操作Redis:高效缓存设计与实战
redis·python·缓存