Script 91: Month Start Campaign Budget Reset

Purpose

Reset Campaign Daily Budget by either 50% or pre-defined amount at start of each month.

To Elaborate

The Python script solves the problem of resetting the daily budget for specific campaigns at the start of each month. The script allows for two options: resetting the budget to 50% of the original value or setting a pre-defined amount. The script identifies the campaigns that need their budgets reset based on a special token in the campaign’s strategy name. The reset values for each campaign are defined in a dictionary. If a campaign does not have a specific reset value, a default trim factor of 0.5 is applied. The script then applies the reset values to the input data, creates an output dataframe with the changed budgets, and rounds the budgets to two decimal places.

Walking Through the Code

  1. The script starts by defining configurable parameters such as the reset token, the reset values for specific campaigns, and the default trim factor.
  2. The script then defines column constants and imports necessary libraries.
  3. The input dataframe is modified to include a new column for the reset budget values.
  4. The script filters the input dataframe to only include campaigns that need their budgets reset based on the strategy name containing the reset token.
  5. A temporary budget column is created in the input dataframe.
  6. The script applies the default trim factor to campaigns with spend and sets the temporary budget column accordingly.
  7. The script then overrides the temporary budget column with the reset values for campaigns that have specific reset values defined.
  8. The modified input dataframe is printed.
  9. The output dataframe is prepared by selecting the relevant columns and rounding the budgets to two decimal places.
  10. The script checks if the output dataframe is empty and prints either the output dataframe or a message indicating it is empty.

Vitals

  • Script ID : 91
  • Client ID / Customer ID: 1306916981 / 60268647
  • Action Type: Bulk Upload
  • Item Changed: Campaign
  • Output Columns: Account, Campaign, Daily Budget
  • Linked Datasource: M1 Report
  • Reference Datasource: None
  • Owner: Michael Huang (mhuang@marinsoftware.com)
  • Created by Michael Huang on 2023-05-05 03:12
  • Last Updated by dwaidhas@marinsoftware.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
#
# Monthly Campaign Budget Reset for Budget Optimizer
#
# Michael S. Huang
# 2023-05-05
#

########## CONFIGURABLE PARAMS - START ########## 

STRATEGY_RESET_TOKEN = "[MONTH_START_RESET_BUDGET]"

# define daily budget reset values for specific campaigns
DAILY_BUDGET_RESET_VALUES = {
    # example
    # "<campaign name>": <daily budget in client currency>
    "Computer Science | Display": 49.34,
    "Computer Science Master's": 88.82,
    "Elementary Education | Display": 31.25,
    "Elementary Education": 11.50,
    "MAT": 62.80,
    "MAT | Display": 12.34, 
    "Early Childhood Edu": 50.0,
}

# default trim factor when campaign has no reset value provided
DAILY_BUDGET_TRIM_FACTOR = 0.5

########## CONFIGURABLE PARAMS - END ############

RPT_COL_CAMPAIGN = 'Campaign'
RPT_COL_ACCOUNT = 'Account'
RPT_COL_CAMPAIGN_STATUS = 'Campaign Status'
RPT_COL_CAMPAIGN_TYPE = 'Campaign Type'
RPT_COL_STRATEGY = 'Strategy'
RPT_COL_DAILY_BUDGET = 'Daily Budget'
RPT_COL_PUB_COST = 'Pub. Cost $'
BULK_COL_ACCOUNT = 'Account'
BULK_COL_CAMPAIGN = 'Campaign'
BULK_COL_DAILY_BUDGET = 'Daily Budget'

outputDf[BULK_COL_DAILY_BUDGET] = "<<YOUR VALUE>>"

#print("inputDf", tableize(inputDf))

# Limit budget reset to campaigns mapped to Strategy with special token in Strategy name
budget_reset_campaigns = inputDf[RPT_COL_STRATEGY].map(lambda x: STRATEGY_RESET_TOKEN in x)
inputDf = inputDf.loc[budget_reset_campaigns].copy()

# define and clear tmp budget column
TMP_DAILY_BUDGET = RPT_COL_DAILY_BUDGET + '_'
inputDf[TMP_DAILY_BUDGET] = np.nan

# first apply default trim factor, but only for campaigns with spend
inputDf.loc[ inputDf[RPT_COL_PUB_COST] > 0, TMP_DAILY_BUDGET] = \
        inputDf[RPT_COL_DAILY_BUDGET] * DAILY_BUDGET_TRIM_FACTOR

# then override with reset value, if provided
for campaign, reset_budget in DAILY_BUDGET_RESET_VALUES.items():
    print(f"Campaign: {campaign}; reset budget: {reset_budget}")
    inputDf.loc[ inputDf[RPT_COL_CAMPAIGN] == campaign, TMP_DAILY_BUDGET] = reset_budget

print("reduced inputDf with reset budget", tableize(inputDf))

# prepare output

cols = [BULK_COL_ACCOUNT, BULK_COL_CAMPAIGN, TMP_DAILY_BUDGET]

# only considered changed if there is a new non-zero budget
changed = inputDf[TMP_DAILY_BUDGET].notna() & inputDf[TMP_DAILY_BUDGET] > 0

# only select changed rows, and round budget to 2 decimal places
outputDf = inputDf.loc[ changed, cols ].copy() \
                  .rename(columns = { \
                    TMP_DAILY_BUDGET: BULK_COL_DAILY_BUDGET \
                  }) \
                  .round(2)

if not outputDf.empty:
  print("outputDf", tableize(outputDf))
else:
  print("Empty outputDf")

Post generated on 2024-03-10 06:34:12 GMT

comments powered by Disqus