Add campaign experiment and control reporting

This commit is contained in:
zouyun
2026-08-28 16:37:10 +08:00
parent 1ae965915a
commit 889e08a18b
4 changed files with 106 additions and 64 deletions
+30 -28
View File
@@ -16,7 +16,7 @@ RAW_CSV="$TMP_DIR/tableau.csv"
if [ -n "${SOURCE_CSV:-}" ]; then
cp "$SOURCE_CSV" "$RAW_CSV"
else
TABLEAU_URL=${TABLEAU_CSV_URL:-'https://mars.ushareit.org/views/DSPSpend/DSPDailyData.csv?:showVizHome=no&%E7%BB%B4%E5%BA%A61=pkg'}
TABLEAU_URL=${TABLEAU_CSV_URL:-'https://mars.ushareit.org/views/DSPSpend/DSPDailyData.csv?:showVizHome=no&%E7%BB%B4%E5%BA%A61=pkg&%E7%BB%B4%E5%BA%A62=adping_id'}
if [ -n "${TABLEAU_COOKIE:-}" ]; then
curl --fail --silent --show-error --location \
--cookie "$TABLEAU_COOKIE" "$TABLEAU_URL" --output "$RAW_CSV"
@@ -25,7 +25,7 @@ else
fi
fi
python3 - "$RAW_CSV" "$ROOT_DIR/data.json" <<'PY'
python3 - "$RAW_CSV" "$ROOT_DIR/campaigns.csv" "$ROOT_DIR/data.json" <<'PY'
import csv
import datetime as dt
import io
@@ -34,7 +34,8 @@ import pathlib
import sys
source_path = pathlib.Path(sys.argv[1])
output_path = pathlib.Path(sys.argv[2])
campaign_path = pathlib.Path(sys.argv[2])
output_path = pathlib.Path(sys.argv[3])
raw = source_path.read_bytes()
head = raw[:500].lower()
if b"<html" in head or b"tableau server" in head:
@@ -48,26 +49,10 @@ else:
sample = text[:4096]
delimiter = "\t" if sample.count("\t") > sample.count(",") else ","
reader = csv.DictReader(io.StringIO(text), delimiter=delimiter)
active_pkgs = [
"com.alibaba.aliexpresshd",
"com.edadeal.android",
"com.fxpro.direct.application",
"com.king.candycrushsaga",
"com.krom.android",
"com.vitastudio.mahjong",
"com.yandex.bank",
"daily.number.match.free.puzzle",
"ru.aliexpress.buyer",
"ru.kinopoisk",
"ru.ozon.app.android",
"tech.im",
"com.esprit.rpg.cntrctfft",
"com.uma.musicvk",
"com.amazon.mShop.android.shopping",
"com.esprit.rpg.lttlefirykng",
]
active = set(active_pkgs)
with campaign_path.open(encoding="utf-8-sig", newline="") as f:
campaigns = list(csv.DictReader(f))
campaign_by_key = {(r["pkg"], r["adping_id"]): r for r in campaigns if r["status"] == "Active"}
active_pkgs = sorted({r["pkg"] for r in campaigns if r["status"] == "Active"})
def pick(row, *names):
for name in names:
@@ -84,16 +69,23 @@ def number(value):
except ValueError:
return 0.0
daily_map = {}
campaign_daily_map = {}
for row in reader:
pkg = pick(row, "维度1", "pkg", "Pkg").strip()
if pkg not in active:
adping_id = pick(row, "维度2", "adping_id", "adpingid").strip()
campaign = campaign_by_key.get((pkg, adping_id))
if not campaign:
continue
date = pick(row, "dt1", "dt", "date").strip()
if not date:
continue
key = (date, pkg)
item = daily_map.setdefault(key, {"date": date, "pkg": pkg, "impression": 0, "click": 0, "conversion": 0, "spend": 0.0})
key = (date, pkg, adping_id)
item = campaign_daily_map.setdefault(key, {
"date": date, "pkg": pkg, "adping_id": adping_id,
"group": campaign["group"], "geo": campaign["geo"],
"platform": campaign["platform"], "owner": campaign["owner"],
"impression": 0, "click": 0, "conversion": 0, "spend": 0.0,
})
item["impression"] += round(number(pick(row, "impression", "Impression")))
item["click"] += round(number(pick(row, "click", "Click")))
item["conversion"] += round(number(pick(row, "conversions", "conversion", "Conversion")))
@@ -112,6 +104,13 @@ def metrics(item):
item["ecpi"] = spend / conv if conv else None
return item
campaign_daily = [metrics(v) for _, v in sorted(campaign_daily_map.items())]
daily_map = {}
for row in campaign_daily:
key = (row["date"], row["pkg"])
item = daily_map.setdefault(key, {"date": row["date"], "pkg": row["pkg"], "impression": 0, "click": 0, "conversion": 0, "spend": 0.0})
for field in ("impression", "click", "conversion", "spend"):
item[field] += row[field]
daily = [metrics(v) for _, v in sorted(daily_map.items())]
summary = []
for pkg in active_pkgs:
@@ -133,6 +132,8 @@ payload = {
"date_start": dates[0] if dates else None,
"date_end": dates[-1] if dates else None,
"active_pkg_count": len(active_pkgs),
"active_campaign_count": len(campaigns),
"campaign_with_data_count": len({(r["pkg"], r["adping_id"]) for r in campaign_daily}),
"pkg_with_data_count": sum(1 for x in summary if x["has_data"]),
"definitions": {
"CTR": "click / impression",
@@ -144,10 +145,11 @@ payload = {
},
"summary": summary,
"daily": daily,
"campaigns": campaigns,
"campaign_daily": campaign_daily,
}
tmp = output_path.with_suffix(".json.tmp")
tmp.write_text(json.dumps(payload, ensure_ascii=False, separators=(",", ":")), encoding="utf-8")
tmp.replace(output_path)
PY