Spaces:
Runtime error
Runtime error
Download src/campaign_parser.py from BinbomJared/DM-Agent: direct link, hf CLI and curl.
- Browser
- Download file 3.97 kB
-
https://huggingface.co/spaces/BinbomJared/DM-Agent/resolve/main/src/campaign_parser.py
- Command line
-
hf download hf://spaces/BinbomJared/DM-Agent/src/campaign_parser.py
-
curl -L -o campaign_parser.py https://huggingface.co/spaces/BinbomJared/DM-Agent/resolve/main/src/campaign_parser.py
3.97 kB
| from __future__ import annotations | |
| """ | |
| Campaign Name 12 字段解析器。 | |
| 按 '_' 分割 campaign_name,提取 12 个标准字段, | |
| 自动归类市场/funnel/平台/优化目标/产品线/受众类型。 | |
| 字段内部用 '-' 连接(如 Bone-Conduction),不与 '_' 分隔符混淆。 | |
| 位置: 1 2 3 4 5 6 7 8 9 10 11 12 | |
| 字段: 市场 funnel 平台 渠道 优化目标 产品线 产品型号 项目类型 受众分类 素材类型 日期 备注 | |
| 示例: US Conversion Meta All Purchase Bone-Conduction Others AO ASC Mix 20260123 coreNumber | |
| """ | |
| import logging | |
| from typing import Any | |
| import pandas as pd | |
| log = logging.getLogger("ad-agent") | |
| VALID_MARKETS = {"US", "CA"} | |
| VALID_FUNNELS = {"Awareness", "Consideration", "Conversion"} | |
| VALID_PLATFORMS = {"Meta", "Google", "Criteo", "Bing", "TikTok"} | |
| VALID_OBJECTIVES = { | |
| "Purchase", "Lead", "ATC", "AtoB", | |
| "Linkclick", "Buttonclick", "Pageview", "PE", | |
| } | |
| AUDIENCE_REMARKETING = "remarketing" | |
| AUDIENCE_ASC = "asc" | |
| AUDIENCE_COLD = "cold" | |
| _FIELD_KEYS = [ | |
| "market", "funnel", "parsed_platform", "channel", | |
| "ad_objective", "product_line", "product_model", "project_type", | |
| "audience_raw", "creative_type", "campaign_date", "note", | |
| ] | |
| _OUTPUT_COLUMNS = _FIELD_KEYS + ["audience_type", "parse_ok", "objective_group"] | |
| def _classify_audience(raw: str) -> str: | |
| upper = raw.upper() | |
| if upper == "RMKT": | |
| return AUDIENCE_REMARKETING | |
| if upper == "ASC": | |
| return AUDIENCE_ASC | |
| return AUDIENCE_COLD | |
| def _derive_objective_group(objective: str | None, audience: str) -> str: | |
| if objective == "Purchase": | |
| if audience == AUDIENCE_REMARKETING: | |
| return "Purchase_RMKT" | |
| if audience == AUDIENCE_ASC: | |
| return "Purchase_ASC" | |
| return "Purchase_Cold" | |
| if objective in VALID_OBJECTIVES: | |
| return objective | |
| return "Other" | |
| def parse_campaign_name(name: str) -> dict[str, Any]: | |
| """ | |
| 解析单个 campaign name,返回 12 个原始字段 + 派生字段。 | |
| 不足 12 段时缺失字段为 None;超出 12 段时多余部分合并到 note。 | |
| """ | |
| parts = str(name).split("_") | |
| result: dict[str, Any] = {} | |
| for i, key in enumerate(_FIELD_KEYS): | |
| if i < len(parts): | |
| if key == "note" and len(parts) > 12: | |
| result[key] = "_".join(parts[11:]) | |
| else: | |
| result[key] = parts[i] | |
| else: | |
| result[key] = None | |
| result["audience_type"] = ( | |
| _classify_audience(result["audience_raw"]) | |
| if result["audience_raw"] | |
| else AUDIENCE_COLD | |
| ) | |
| result["parse_ok"] = ( | |
| len(parts) >= 5 | |
| and result.get("market") in VALID_MARKETS | |
| and result.get("funnel") in VALID_FUNNELS | |
| ) | |
| result["objective_group"] = _derive_objective_group( | |
| result.get("ad_objective"), result["audience_type"] | |
| ) | |
| return result | |
| def enrich_dataframe(df: pd.DataFrame) -> pd.DataFrame: | |
| """ | |
| 批量解析 campaign_name 列,新增解析字段列。返回新 DataFrame。 | |
| """ | |
| if "campaign_name" not in df.columns: | |
| log.warning("DataFrame 中没有 campaign_name 列,跳过解析") | |
| return df | |
| df = df.copy() | |
| parsed = df["campaign_name"].apply(parse_campaign_name) | |
| parsed_df = pd.DataFrame(parsed.tolist(), index=df.index) | |
| for col in _OUTPUT_COLUMNS: | |
| if col in parsed_df.columns: | |
| df[col] = parsed_df[col] | |
| ok_count = df["parse_ok"].sum() if "parse_ok" in df.columns else 0 | |
| total = len(df) | |
| if total > 0: | |
| rate = ok_count / total * 100 | |
| log.info(f"Campaign name 解析: {ok_count}/{total} 成功 ({rate:.1f}%)") | |
| if rate < 90: | |
| log.warning("解析成功率低于 90%,可能存在命名不规范的 campaign") | |
| return df | |