基于python和streamlit实现的便利店商品推荐大屏,针对选择困难症消费者。
import streamlit as st
import pandas as pd
import numpy as np
import altair as alt
from datetime import datetime, timedelta
import time
# 模拟数据生成
def generate_data():
np.random.seed(42)
products = ['咖啡+三明治', '泡面+火腿肠', '酸奶+水果盒', '薯片+可乐', '饭团+茶饮',
'巧克力+能量棒', '冰激凌+饼干', '寿司+味增汤', '沙拉+果汁', '关东煮套餐']
data = pd.DataFrame({
'组合名称': products,
'本周销量': np.random.randint(100, 500, len(products)),
'总价(元)': [15, 12, 18, 10, 20, 25, 13, 22, 17, 16],
'场景标签': ['早餐', '宵夜', '健康', '休闲', '午餐', '健身', '零食', '日式', '轻食', '热食'],
'库存状态': ['充足'] * 8 + ['低库存'] * 2
})
return data
# 实时趋势模拟
def realtime_trend():
timestamps = [datetime.now() - timedelta(hours=i) for i in range(24)]
return pd.DataFrame({
'时间': timestamps,
'销量': np.random.poisson(lam=50, size=24).cumsum()
})
# 大屏布局
def main():
st.set_page_config(layout="wide")
st.title("🏪 购物决策")
# 数据加载
data = generate_data()
trend_data = realtime_trend()
# 第一行:核心指标
col1, col2, col3 = st.columns(3)
with col1:
st.metric("🔥 今日最热组合", "泡面+火腿肠", "+15%销量增长")
with col2:
st.metric("🕒 最佳购买时段", "20:00-22:00", "销量峰值")
with col3:
st.metric("📈 实时订单量", np.random.randint(50, 200), "环比+8%")
# 第二行:主视觉区
tab1, tab2, tab3 = st.tabs(["TOP10组合", "实时趋势", "场景导航"])
with tab1:
# 组合排行榜(带交互)
c = alt.Chart(data).mark_bar().encode(
x='本周销量:Q',
y=alt.Y('组合名称:N', sort='-x'),
color=alt.Color('总价(元):Q', scale=alt.Scale(scheme='goldred')),
tooltip=['组合名称', '本周销量', '总价(元)', '库存状态']
).properties(height=400)
st.altair_chart(c, use_container_width=True)
with tab2:
# 实时趋势图
line_chart = alt.Chart(trend_data).mark_line().encode(
x='时间:T',
y='销量:Q',
color=alt.value('#FF6B6B')
).properties(height=400)
st.altair_chart(line_chart, use_container_width=True)
with tab3:
# 场景导航按钮
selected_scene = st.radio("选择消费场景:",
["早餐", "宵夜", "健康", "全部"],
horizontal=True)
filtered_data = data[data['场景标签'] == selected_scene] if selected_scene != "全部" else data
st.write(f"### {selected_scene}推荐组合")
cols = st.columns(3)
for idx, (_, row) in enumerate(filtered_data.iterrows()):
with cols[idx % 3]:
st.image(f"https://picsum.photos/200/100?random={idx}",
use_column_width=True)
st.caption(f"**{row['组合名称']}** | ¥{row['总价(元)']}")
st.progress(row['本周销量'] / 500, text=f"本周销量 {row['本周销量']}份")
# 第三行:交互模块
with st.expander("🎮 组合探索游戏"):
left, right = st.columns(2)
with left:
st.subheader("🔀 随机惊喜生成器")
if st.button("生成我的幸运组合"):
combo = np.random.choice(data['组合名称'], 2, replace=False)
st.success(f"🎉 推荐组合:{combo[0]} + {combo[1]} 立减3元!")
with right:
st.subheader("🆚 组合PK投票")
vote_options = np.random.choice(data['组合名称'], 2, replace=False)
vote = st.radio("哪个更吸引你?", vote_options)
st.write(f"当前票数: {np.random.randint(50, 100)} vs {np.random.randint(50, 100)}")
# 运行程序
if __name__ == "__main__":
main()