Script 361: New Launch Updates Round 3

Purpose

The Python script updates the status, target CPA, bid strategy, and maturity of new launch campaigns based on specific performance criteria.

To Elaborate

The script is designed to manage and update new launch advertising campaigns by adjusting their status, target cost-per-acquisition (tCPA), bid strategy, and maturity level based on predefined performance criteria. These criteria are primarily based on the Return on Advertising Spend (ROAS) metric. The script evaluates each campaign’s ROAS and applies adjustments to the campaign’s daily budget, tCPA, and status if they fall within specified ROAS ranges. The goal is to optimize campaign performance by pausing underperforming campaigns and enhancing those that meet or exceed performance expectations. This process ensures that advertising budgets are allocated efficiently, maximizing the return on investment for each campaign.

Walking Through the Code

  1. Initialization and Setup
    • The script begins by defining constants for column names used in the input and output data frames.
    • It sets up a parameter current_maturity to track the maturity level of campaigns from the input data.
  2. Defining Adjustment Criteria
    • A list of tuples, newlaunch_adj_criteria, is defined to specify the conditions under which campaign adjustments should be made. Each tuple contains minimum and maximum ROAS values, budget and tCPA adjustments, and the desired status and maturity level.
  3. Temporary Columns for Adjustments
    • Temporary columns are created in the input data frame to store new values for status, budget, tCPA, and maturity. These columns are initialized with NaN to ensure they are cleared before processing.
  4. Applying Adjustment Criteria
    • The script iterates over each set of criteria in newlaunch_adj_criteria.
    • For each campaign that matches the ROAS criteria, it calculates new budget and tCPA values, updates the status and maturity, and stores these in the temporary columns.
  5. Identifying and Processing Changes
    • After applying adjustments, the script identifies campaigns with changes in budget, tCPA, status, or maturity.
    • It creates an output data frame containing only the campaigns with changes, renaming columns to match the expected output format.
  6. Output
    • The script prints the final output data frame, which includes only the campaigns that have undergone adjustments.

Vitals

  • Script ID : 361
  • Client ID / Customer ID: 1306925431 / 60269477
  • Action Type: Bulk Upload (Preview)
  • Item Changed: Campaign
  • Output Columns: Account, Campaign, Daily Budget, Publisher Target CPA, Status, Campaign Maturity
  • Linked Datasource: M1 Report
  • Reference Datasource: None
  • Owner: Byron Porter (bporter@marinsoftware.com)
  • Created by Byron Porter on 2023-10-16 22:16
  • Last Updated by simon@rainmakeradventures.com on 2023-12-06 04:01
> See it in Action

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#
# Update, Status, tCPA, Bid Strategy, and or Campaign Maturity for New Launch Campaigns
#  
#  
#
#
# Author: Byron Porter
# Date: 2023-10-16
#


RPT_COL_CAMPAIGN = 'Campaign'
RPT_COL_ACCOUNT = 'Account'
RPT_COL_CAMPAIGN_STATUS = 'Campaign Status'
RPT_COL_DAILY_BUDGET = 'Daily Budget'
RPT_COL_PUBLISHER_BIDSTRATEGY = 'Publisher Bid Strategy'
RPT_COL_PUBLISHER_TARGETCPA = 'Publisher Target CPA'
RPT_COL_PUB_COST = 'Pub. Cost $'
RPT_COL_REVENUE = 'Revenue $'
RPT_COL_ROAS = 'CLICKS ROAS'
RPT_COL_RPC = 'Rev./Click $'
RPT_COL_CLICKS = 'Clicks'
RPT_COL_MATURITY = 'Campaign Maturity'

BULK_COL_ACCOUNT = 'Account'
BULK_COL_CAMPAIGN = 'Campaign'
BULK_COL_STATUS = 'Status'
BULK_COL_DAILY_BUDGET = 'Daily Budget'
BULK_COL_PUBLISHER_TARGETCPA = 'Publisher Target CPA'
BULK_COL_PUBLISHER_BIDSTRATEGY = 'Publisher Bid Strategy'
BULK_COL_MATURITY = 'Campaign Maturity'


#set maturity parameter value so that it can be used in tuple
current_maturity = inputDf[RPT_COL_MATURITY]

# Define thesholds/conditions for updating New Launch Campaign values
newlaunch_adj_criteria = [
    # format:
    # (min roas, max roas, budget adj, tCPA adj, status, maturity)
    (.70, .75, 0.0, 0.0, 'PAUSE', current_maturity),
    (.75, 1, 0.0, .10, 'ACTIVE', 'Mature'),
    (1, 100, .25, 0.0, 'ACTIVE', 'Mature')
]


# temp columns to house new values and make sure all values are cleared out
TMP_STATUS = RPT_COL_CAMPAIGN_STATUS + '_'
inputDf[TMP_STATUS] = np.nan

#TMP_PUB_STRATEGY = RPT_COL_PUBLISHER_BIDSTRATEGY + '_'
#inputDf[TMP_PUB_STRATEGY] = np.nan

TMP_BUDGET = RPT_COL_DAILY_BUDGET + '_'
inputDf[TMP_BUDGET] = np.nan

TMP_MATURITY = RPT_COL_MATURITY + '_'
inputDf[TMP_MATURITY] = np.nan

TMP_TARGETCPA = RPT_COL_PUBLISHER_TARGETCPA + '_'
inputDf[TMP_TARGETCPA] = np.nan


# Convert the 'Date' column to datetime format
#inputDf['Date'] = pd.to_datetime(inputDf['Date'], format='%m/%d/%y')


# loop through each adj criteria tuple and apply
for (min_roas, max_roas, budget_adj, tcpa_adj, status, maturity) in newlaunch_adj_criteria:

    print(f"Applying adj criteria: min roas={min_roas}, max roas={max_roas}, budget adj={budget_adj}, tcpa adj={tcpa_adj}, status ={status}, maturity={maturity}")

    matched_campaigns = (inputDf[RPT_COL_ROAS] >= min_roas) & \
                        (inputDf[RPT_COL_ROAS] < max_roas)
                        

    if sum(matched_campaigns) > 0:
        print("matched campaigns: ", sum(matched_campaigns))

        new_budget = inputDf.loc[matched_campaigns, RPT_COL_DAILY_BUDGET] * (1 + budget_adj)
        inputDf.loc[ matched_campaigns, TMP_BUDGET ] = new_budget

        new_tcpa = inputDf.loc[matched_campaigns, RPT_COL_PUBLISHER_TARGETCPA] * (1 - tcpa_adj)
        inputDf.loc[ matched_campaigns, TMP_TARGETCPA ] = new_tcpa

        inputDf.loc[ matched_campaigns, TMP_STATUS] = status

        inputDf.loc[ matched_campaigns, TMP_MATURITY] = maturity

        print("adj applied", tableize(inputDf.loc[matched_campaigns]))


# find changed campaigns
changed = (inputDf[TMP_BUDGET].notnull() & (inputDf[RPT_COL_DAILY_BUDGET] != inputDf[TMP_BUDGET])) | \
          (inputDf[TMP_TARGETCPA].notnull() & (inputDf[RPT_COL_PUBLISHER_TARGETCPA] != inputDf[TMP_TARGETCPA])) | \
          (inputDf[TMP_STATUS].notnull() & (inputDf[RPT_COL_CAMPAIGN_STATUS] != inputDf[TMP_STATUS])) | \
          (inputDf[TMP_MATURITY].notnull() & (inputDf[RPT_COL_MATURITY] != inputDf[TMP_MATURITY]))

if sum(changed) > 0:

    print("== Campaigns with Changed Adj ==", tableize(inputDf.loc[changed]))

    # only select changed rows
    cols = [RPT_COL_ACCOUNT, RPT_COL_CAMPAIGN, TMP_BUDGET, TMP_TARGETCPA, TMP_STATUS, TMP_MATURITY]
    outputDf = inputDf.loc[ changed, cols ].copy() \
                    .rename(columns = { \
                        TMP_BUDGET: BULK_COL_DAILY_BUDGET, \
                        TMP_TARGETCPA: BULK_COL_PUBLISHER_TARGETCPA, \
                        TMP_STATUS: BULK_COL_STATUS, \
                        TMP_MATURITY: BULK_COL_MATURITY \
                    })
    #nodateDf[RPT_COL_LAST_TCPA_BUDGET_UPDATE] = datetime.date.today()
else:
    
    print("Empty inputDf")
    outputDf = outputDf.iloc[0:0]

print("outputDf", tableize(outputDf))

Post generated on 2024-11-27 06:58:46 GMT

comments powered by Disqus