import pandas as pd
import streamlit as st
import plotly.express as px
import plotly.graph_objects as go
# -------------------------- 1. 初始化配置 & 加载数据 --------------------------
@st.cache_data
def load_data():
df = pd.read_csv("wukong_cleaned.csv", parse_dates=["发布时间(2024年)"])
df["是否推荐"] = df["是否推荐"].map({"推荐": 1, "不推荐": 0}) # 预处理
return df
df = load_data()
# 侧边栏日期筛选
st.sidebar.header("日期筛选")
min_date = df["发布时间(2024年)"].min().date()
max_date = df["发布时间(2024年)"].max().date()
selected_date = st.sidebar.date_input(
"选择日期",
value=max_date,
min_value=min_date,
max_value=max_date
)
# -------------------------- 2. 需求1:每日评价人数曲线 --------------------------
st.header("(1)用户每日评价人数曲线")
daily_stats = df.groupby(df["发布时间(2024年)"].dt.date).agg(
评价人数=("用户", "nunique"),
).reset_index()
fig_line = px.line(
daily_stats,
x="发布时间(2024年)",
y="评价人数",
title="每日评价用户人数变化",
labels={"发布时间(2024年)": "日期", "评价人数": "评价人数"},
markers=True
)
fig_line.update_traces(
hoverinfo="name+x+y",
line=dict(color="royalblue", width=2)
)
st.plotly_chart(fig_line, use_container_width=True)
# -------------------------- 3. 需求2:每日推荐/不推荐饼图 --------------------------
st.header("(2)用户每日评级推荐/不推荐饼图")
daily_data = df[df["发布时间(2024年)"].dt.date == selected_date]
if daily_data.empty:
st.warning(f"无 {selected_date} 的评价数据,请选择其他日期!")
else:
recommend_count = daily_data["是否推荐"].sum()
not_recommend_count = len(daily_data) - recommend_count
fig_pie = px.pie(
values=[recommend_count, not_recommend_count],
names=["推荐", "不推荐"],
title=f"{selected_date} 推荐/不推荐分布",
color_discrete_map={"推荐": "#66BB6A", "不推荐": "#EF5350"}
)
fig_pie.update_traces(
hoverinfo="label+percent+value",
textinfo="percent",
textposition="inside"
)
st.plotly_chart(fig_pie, use_container_width=True)
# -------------------------- 4. 需求3:游戏时长与是否推荐的关系(替换箱线图为散点图+密度热图) --------------------------
st.header("(3)游戏时长与是否推荐的关系分析")
# 4.1 散点图 + 回归线(展示趋势)
st.subheader("游戏时长与推荐倾向关系(散点图)")
fig_scatter = px.scatter(
df,
x="大圣游戏时长",
y="是否推荐",
title="游戏时长 vs 是否推荐",
labels={"大圣游戏时长": "游戏时长(小时)", "是否推荐": "推荐倾向"},
trendline="ols", # 添加回归线(线性回归)
color="是否推荐",
color_discrete_map={1: "#66BB6A", 0: "#EF5350"},
opacity=0.6,
hover_data=["用户"] # 悬停显示用户ID
)
# 自定义回归线显示
fig_scatter.update_layout(
legend=dict(title="是否推荐"),
annotations=[
dict(
x=0.5,
y=-0.15,
xref="paper",
yref="paper",
text="回归线显示游戏时长与推荐倾向的关系",
showarrow=False,
font=dict(size=10)
)
]
)
st.plotly_chart(fig_scatter, use_container_width=True)
# 4.3 时长区间推荐率(保留柱状图)
st.subheader("游戏时长区间与推荐率关系(柱状图)")
df["时长区间"] = pd.cut(
df["大圣游戏时长"],
bins=[0, 5, 10, float("inf")],
labels=["0-5小时", "5-10小时", "10小时以上"]
)
duration_recommend = df.groupby("时长区间", observed=False)["是否推荐"].mean().reset_index()
fig_bar = px.bar(
duration_recommend,
x="时长区间",
y="是否推荐",
title="游戏时长区间与推荐率关系",
labels={"时长区间": "游戏时长区间", "是否推荐": "推荐率"},
color_discrete_map={"是否推荐": "#66BB6A"}
)
fig_bar.update_traces(
hoverinfo="x+y",
texttemplate="%{y:.1%}",
textposition="outside"
)
fig_bar.update_yaxes(tickformat=".0%", range=[0, 1])
st.plotly_chart(fig_bar, use_container_width=True)
浙公网安备 33010602011771号