源代码下载:https://pan.quark.cn/s/1b691d70d0af
下载方式2: https://pan.baidu.com/s/1M5evnzw1O6EdycVuwkP4kA?pwd=buue 提取码: buue

一、引言

本系统借助Python语言以及Streamlit框架的便捷可视化特性,实现了基于关键词的食谱推荐功能,并对推荐结果进行了直观的统计展示。
在这里插入图片描述

二、关键函数解析

2.1 食材数据解析函数parse_ingredients

def parse_ingredients(ingredients_json):
    """解析JSON格式的食材数据,兼容字典列表和字符串列表两种格式"""
    try:
        ingredients = json.loads(ingredients_json)
        ingredient_names = []
        formatted_text = ""

        for item in ingredients:
            if isinstance(item, dict):
                # 处理字典格式(原逻辑)
                name = item.get("name", "未知食材")
                amount = item.get("amount", "适量")
            else:
                # 处理字符串格式(新增逻辑)
                name = str(item).strip()  # 转换为字符串并去除首尾空格
                amount = "适量"  # 默认为"适量"

            ingredient_names.append(name.lower())
            formatted_text += f"- {name}: {amount}\n"

        return formatted_text.strip(), ingredient_names
    except (json.JSONDecodeError, TypeError):
        # 保持原错误处理逻辑
        return str(ingredients_json), []

该函数旨在解析食材数据,支持两种格式:字典列表和字符串列表。通过json.loads尝试将输入解析为JSON数据,若解析成功,遍历其中元素。对于字典格式,提取食材名称和用量;对于字符串格式,将字符串作为食材名称并默认用量为“适量”。最后返回格式化后的食材文本及食材名称列表,若解析失败则返回原数据及空列表。

2.2 食谱推荐函数recommend_recipes

def recommend_recipes(keywords):
    df = pd.read_csv('E:\\pycharm_workspace\\食谱数据\\1_Recipe_csv.csv')
    matching_indices = []

    for index, row in df.iterrows():
        title_text = str(row['recipe_title']).lower()
        description_text = str(row['description']).lower()

        ingredients_json = str(row['ingredients'])
        _, ingredient_names = parse_ingredients(ingredients_json)  # 获取食材名称列表
        ingredients_text = " ".join(ingredient_names)  # 转换为空格分隔的文本用于匹配

        # 检查关键词是否出现在标题、描述或解析后的食材名称中
        if all(keyword in title_text or keyword in description_text or keyword in ingredients_text
               for keyword in keywords):
            matching_indices.append(index)

    matching_recipes = df.loc[matching_indices]
    return matching_recipes

此函数根据用户输入的关键词推荐食谱。它读取包含食谱信息的CSV文件,遍历每一行数据,将食谱标题、描述以及解析后的食材名称转换为小写并拼接成文本。检查每个关键词是否出现在这些文本中,若都出现则记录该行索引。最后返回匹配关键词的食谱数据。

2.3 类别统计绘图函数plot_category_counts

def plot_category_counts(matching_recipes):
    # 统计不同类别中推荐食谱的数量
    category_counts = matching_recipes['category'].value_counts()

    # 设置图片清晰度
    plt.rcParams['figure.dpi'] = 300

    # 设置中文字体
    plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei']

    # 绘制柱状图
    plt.figure(figsize=(10, 6))
    category_counts.plot(kind='bar', color='skyblue')
    plt.title('不同类别中推荐食谱的数量')
    plt.xlabel('类别')
    plt.ylabel('食谱数量')
    plt.xticks(rotation=45)
    plt.tight_layout()
    return plt

该函数统计推荐食谱在不同类别中的数量,并绘制柱状图进行可视化展示。设置图片清晰度和中文字体,利用value_counts统计每个类别中食谱的数量,然后绘制柱状图,标注图表标题、坐标轴标签,并调整刻度旋转角度以确保图表可读性。

三、Streamlit交互界面实现

st.title('食谱推荐系统')

keyword_input = st.text_input('请输入关键词(用空格分隔)')
keywords = keyword_input.lower().split() if keyword_input else []

if st.button('推荐食谱'):
    if keywords:
        recommended_recipes = recommend_recipes(keywords)
        if not recommended_recipes.empty:
            st.write("以下是根据关键词推荐的食谱:")
            sorted_recipes = recommended_recipes.sort_values('recipe_title')
            cols_per_row = 3
            rows = (len(sorted_recipes) + cols_per_row - 1) // cols_per_row

            fig = plot_category_counts(recommended_recipes)
            st.pyplot(fig)
            for row_idx in range(rows):
                cols = st.columns(cols_per_row)
                for col_idx in range(cols_per_row):
                    recipe_idx = row_idx * cols_per_row + col_idx
                    if recipe_idx < len(sorted_recipes):
                        recipe = sorted_recipes.iloc[recipe_idx]
                        with cols[col_idx]:
                            st.markdown(f"### {recipe['recipe_title']}")
                            st.caption(f"**类别:** {recipe['category']}")

                            description = recipe['description']
                            if description and len(description) > 100:
                                st.write(f"**描述:** {description[:100]}...")
                            else:
                                st.write(f"**描述:** {description or '无描述信息'}")

                            # {{ edit_4: 展示格式化后的食材列表 }}
                            with st.expander("查看食材"):
                                ingredients_json = str(recipe['ingredients'])
                                formatted_ingredients, _ = parse_ingredients(ingredients_json)
                                st.text(formatted_ingredients)  # 显示解析后的结构化食材

                            st.divider()
        else:
            st.write("没有找到匹配关键词的食谱。")
    else:
        st.write("请输入关键词。")

通过Streamlit构建用户交互界面。设置页面标题为“食谱推荐系统”,提供文本输入框让用户输入关键词,并将输入转换为小写并按空格分割成关键词列表。当用户点击“推荐食谱”按钮时,若有关键词输入,则调用recommend_recipes函数获取推荐食谱。若有推荐结果,对食谱按标题排序,绘制推荐食谱类别统计柱状图并展示。同时,以每行3列的布局展示每个推荐食谱的标题、类别、简短描述及食材信息。若未找到匹配食谱或未输入关键词,则给出相应提示。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐