|
@@ -154,7 +154,63 @@ for cat in valid_categories:
|
|
|
cells.append("<td>-</td>")
|
|
cells.append("<td>-</td>")
|
|
|
recommend_rows.append("<tr>" + "".join(cells) + "</tr>")
|
|
recommend_rows.append("<tr>" + "".join(cells) + "</tr>")
|
|
|
|
|
|
|
|
-# 5. 趋势数据
|
|
|
|
|
|
|
+# 5. 二级品类热力图
|
|
|
|
|
+channel_cat2 = df.groupby(['channel', 'merge一级品类', 'merge二级品类']).apply(
|
|
|
|
|
+ lambda x: pd.Series({
|
|
|
|
|
+ '点击uv': x['点击uv'].sum(),
|
|
|
|
|
+ '回流率': (x['再分享回流率'] * x['点击uv']).sum() / x['点击uv'].sum() if x['点击uv'].sum() > 0 else 0
|
|
|
|
|
+ }), include_groups=False
|
|
|
|
|
+).reset_index()
|
|
|
|
|
+
|
|
|
|
|
+# 创建二级品类标签
|
|
|
|
|
+channel_cat2['cat2_label'] = channel_cat2.apply(
|
|
|
|
|
+ lambda r: f"{str(r['merge一级品类'])[:6]}/{str(r['merge二级品类'])[:8]}"
|
|
|
|
|
+ if pd.notna(r['merge二级品类']) else str(r['merge一级品类'])[:12], axis=1
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+# 二级品类汇总
|
|
|
|
|
+cat2_stats = channel_cat2.groupby('cat2_label').agg({'点击uv': 'sum'}).reset_index()
|
|
|
|
|
+cat2_stats = cat2_stats[cat2_stats['点击uv'] >= 1000].sort_values('点击uv', ascending=False)
|
|
|
|
|
+valid_cat2_labels = cat2_stats.head(20)['cat2_label'].tolist()
|
|
|
|
|
+
|
|
|
|
|
+pivot_cat2_ror = channel_cat2.pivot_table(index='cat2_label', columns='channel', values='回流率')
|
|
|
|
|
+pivot_cat2_uv = channel_cat2.pivot_table(index='cat2_label', columns='channel', values='点击uv', fill_value=0)
|
|
|
|
|
+
|
|
|
|
|
+# 二级品类回流率热力图
|
|
|
|
|
+cat2_ror_header = "<tr><th>二级品类</th>" + "".join([f"<th>{c[:10]}</th>" for c in heatmap_cols]) + "</tr>"
|
|
|
|
|
+cat2_ror_rows = []
|
|
|
|
|
+for cat2 in valid_cat2_labels:
|
|
|
|
|
+ if cat2 not in pivot_cat2_ror.index:
|
|
|
|
|
+ continue
|
|
|
|
|
+ cells = [f"<td>{cat2[:15]}</td>"]
|
|
|
|
|
+ for ch in heatmap_cols:
|
|
|
|
|
+ if ch in pivot_cat2_ror.columns and pd.notna(pivot_cat2_ror.loc[cat2, ch]):
|
|
|
|
|
+ val = pivot_cat2_ror.loc[cat2, ch] * 100
|
|
|
|
|
+ cls = get_cell_class(val)
|
|
|
|
|
+ cells.append(f'<td class="{cls}">{val:.1f}%</td>')
|
|
|
|
|
+ else:
|
|
|
|
|
+ cells.append("<td>-</td>")
|
|
|
|
|
+ cat2_ror_rows.append("<tr>" + "".join(cells) + "</tr>")
|
|
|
|
|
+
|
|
|
|
|
+# 二级品类UV热力图
|
|
|
|
|
+cat2_uv_rows = []
|
|
|
|
|
+for cat2 in valid_cat2_labels:
|
|
|
|
|
+ if cat2 not in pivot_cat2_uv.index:
|
|
|
|
|
+ continue
|
|
|
|
|
+ cells = [f"<td>{cat2[:15]}</td>"]
|
|
|
|
|
+ for ch in heatmap_cols:
|
|
|
|
|
+ if ch in pivot_cat2_uv.columns:
|
|
|
|
|
+ val = pivot_cat2_uv.loc[cat2, ch]
|
|
|
|
|
+ if val > 0:
|
|
|
|
|
+ cls = get_uv_class(val)
|
|
|
|
|
+ cells.append(f'<td class="{cls}">{int(val):,}</td>')
|
|
|
|
|
+ else:
|
|
|
|
|
+ cells.append("<td>-</td>")
|
|
|
|
|
+ else:
|
|
|
|
|
+ cells.append("<td>-</td>")
|
|
|
|
|
+ cat2_uv_rows.append("<tr>" + "".join(cells) + "</tr>")
|
|
|
|
|
+
|
|
|
|
|
+# 6. 趋势数据
|
|
|
top_channels = channel_stats.head(6)['channel'].tolist()
|
|
top_channels = channel_stats.head(6)['channel'].tolist()
|
|
|
trend_data = {}
|
|
trend_data = {}
|
|
|
for ch in top_channels:
|
|
for ch in top_channels:
|
|
@@ -293,12 +349,38 @@ html_content = f"""<!DOCTYPE html>
|
|
|
</table>
|
|
</table>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <h2>5. 每日回流率趋势</h2>
|
|
|
|
|
|
|
+ <h2>5. 渠道×二级品类 回流率矩阵</h2>
|
|
|
|
|
+ <div class="chart-container heatmap matrix-section">
|
|
|
|
|
+ <div class="legend">
|
|
|
|
|
+ <span class="high">高 >30%</span>
|
|
|
|
|
+ <span class="medium">中 15-30%</span>
|
|
|
|
|
+ <span class="low">低 <15%</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <table>
|
|
|
|
|
+ {cat2_ror_header}
|
|
|
|
|
+ {"".join(cat2_ror_rows)}
|
|
|
|
|
+ </table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <h2>6. 渠道×二级品类 点击UV矩阵</h2>
|
|
|
|
|
+ <div class="chart-container heatmap matrix-section">
|
|
|
|
|
+ <div class="legend">
|
|
|
|
|
+ <span class="high">高 >5万</span>
|
|
|
|
|
+ <span class="medium">中 1-5万</span>
|
|
|
|
|
+ <span class="low">低 <1万</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <table>
|
|
|
|
|
+ {cat2_ror_header}
|
|
|
|
|
+ {"".join(cat2_uv_rows)}
|
|
|
|
|
+ </table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <h2>7. 每日回流率趋势</h2>
|
|
|
<div class="chart-container">
|
|
<div class="chart-container">
|
|
|
<canvas id="trendChart"></canvas>
|
|
<canvas id="trendChart"></canvas>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <h2>6. UV vs 回流率 散点分布</h2>
|
|
|
|
|
|
|
+ <h2>8. UV vs 回流率 散点分布</h2>
|
|
|
<div class="chart-container">
|
|
<div class="chart-container">
|
|
|
<canvas id="scatterChart"></canvas>
|
|
<canvas id="scatterChart"></canvas>
|
|
|
</div>
|
|
</div>
|