Просмотр исходного кода

feat(渠道效果分析): 增加矩阵视图和Top列表

- 渠道×品类 回流率矩阵表格
- 各品类 Top 3 渠道
- 各渠道 Top 5 品类(含UV明细)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
yangxiaohui 2 месяцев назад
Родитель
Сommit
2dad88978e
1 измененных файлов с 38 добавлено и 12 удалено
  1. 38 12
      tasks/渠道效果分析/analyze.py

+ 38 - 12
tasks/渠道效果分析/analyze.py

@@ -127,37 +127,63 @@ valid_channels = main_channels[:8]
 log(f"品类数: {len(valid_categories)}, 渠道数: {len(valid_channels)}")
 log(f"品类数: {len(valid_categories)}, 渠道数: {len(valid_channels)}")
 log()
 log()
 
 
-log("【各品类最佳渠道】")
+# 输出矩阵
+log("【渠道×品类 回流率矩阵】")
+log("-" * 100)
+
+# 简化渠道名用于表头
+ch_short = {ch: ch[:8] for ch in valid_channels}
+header = f"{'品类':<15}" + "".join([f"{ch_short[ch]:>12}" for ch in valid_channels])
+log(header)
+log("-" * 100)
+
+for category in valid_categories:
+    if category not in pivot_ror.index:
+        continue
+    cat_name = str(category)[:13] if pd.notna(category) else '(空)'
+    row_str = f"{cat_name:<15}"
+    for ch in valid_channels:
+        if ch in pivot_ror.columns and pd.notna(pivot_ror.loc[category, ch]):
+            rate = pivot_ror.loc[category, ch]
+            row_str += f"{rate:>12.1%}"
+        else:
+            row_str += f"{'--':>12}"
+    log(row_str)
+
+log()
+
+log("【各品类 Top 3 渠道】")
 log("-" * 80)
 log("-" * 80)
 
 
 for category in valid_categories:
 for category in valid_categories:
     if category not in pivot_ror.index:
     if category not in pivot_ror.index:
         continue
         continue
-    row = pivot_ror.loc[category, [c for c in valid_channels if c in pivot_ror.columns]].dropna()
+    row = pivot_ror.loc[category, [c for c in valid_channels if c in pivot_ror.columns]].dropna().sort_values(ascending=False)
     if len(row) == 0:
     if len(row) == 0:
         continue
         continue
-    best_ch = row.idxmax()
-    best_ror = row.max()
-    cat_uv = int(pivot_uv.loc[category].sum())
     cat_name = str(category)[:15] if pd.notna(category) else '(空)'
     cat_name = str(category)[:15] if pd.notna(category) else '(空)'
-    log(f"  {cat_name:<17} UV={cat_uv:>8,} → {best_ch:<20} 回流率={best_ror:.1%}")
+    cat_uv = int(pivot_uv.loc[category].sum())
+    top3 = ", ".join([f"{ch[:10]}({row[ch]:.0%})" for ch in row.head(3).index])
+    log(f"  {cat_name:<17} UV={cat_uv:>8,} → {top3}")
 
 
 log()
 log()
 
 
-log("【各渠道最佳品类】")
+log("【各渠道 Top 5 品类】")
 log("-" * 80)
 log("-" * 80)
 
 
 for ch in valid_channels:
 for ch in valid_channels:
     if ch not in pivot_ror.columns:
     if ch not in pivot_ror.columns:
         continue
         continue
-    col = pivot_ror.loc[valid_categories, ch].dropna()
+    col = pivot_ror.loc[valid_categories, ch].dropna().sort_values(ascending=False)
     if len(col) == 0:
     if len(col) == 0:
         continue
         continue
-    best_cat = col.idxmax()
-    best_ror = col.max()
     ch_uv = int(channel_stats[channel_stats['channel'] == ch]['点击uv'].values[0])
     ch_uv = int(channel_stats[channel_stats['channel'] == ch]['点击uv'].values[0])
-    cat_name = str(best_cat)[:15] if pd.notna(best_cat) else '(空)'
-    log(f"  {ch:<25} UV={ch_uv:>10,} → {cat_name:<15} 回流率={best_ror:.1%}")
+    log(f"  {ch:<25} UV={ch_uv:>10,}")
+    for cat in col.head(5).index:
+        cat_name = str(cat)[:15] if pd.notna(cat) else '(空)'
+        cat_uv = int(pivot_uv.loc[cat, ch]) if ch in pivot_uv.columns else 0
+        log(f"      {cat_name:<17} UV={cat_uv:>8,} 回流率={col[cat]:.1%}")
+    log()
 
 
 log()
 log()