Script 407: New Launch Updates Round 1

Purpose

Python script to update the status, tCPA, bid strategy, and campaign maturity for new launch campaigns.

To Elaborate

This Python script is designed to update the status, tCPA (target cost per acquisition), bid strategy, and campaign maturity for new launch campaigns. It takes input data from a DataFrame and applies certain business rules to determine the new values for these parameters. The script then outputs the updated values in a new DataFrame.

Walking Through the Code

  1. The script defines various column constants for the input and output DataFrames.
  2. It sets the current strategy parameter value based on user input.
  3. Temporary columns are created in the input DataFrame to store new values and ensure all values are cleared out.
  4. Two temporary DataFrames, moreDf and lessDf, are defined to store campaigns with 5 or more clicks and campaigns with less than 5 clicks, respectively.
  5. The script checks if campaigns have 5 or more clicks using a boolean expression.
  6. Based on the click count, the script sets new values for the temporary columns using boolean expressions and thresholds for revenue per click (Rev/Click) and spend.
  7. The script prints the current after and before DataFrames for debugging purposes.
  8. The script identifies campaigns with changed adjustments by comparing the original values with the new values in the temporary columns.
  9. If there are changed campaigns, the script selects the relevant columns and renames them to match the output DataFrame structure.
  10. The script merges the non-empty DataFrames and prints the resulting output DataFrame.
  11. If there are no changed campaigns, the script prints an empty output DataFrame.

Vitals

  • Script ID : 407
  • Client ID / Customer ID: 1306925431 / 60269477
  • Action Type: Bulk Upload (Preview)
  • Item Changed: Campaign
  • Output Columns: Account, Campaign, Status, Publisher Bid Strategy, Publisher Target CPA
  • Linked Datasource: M1 Report
  • Reference Datasource: None
  • Owner: Byron Porter (bporter@marinsoftware.com)
  • Created by Byron Porter on 2023-10-24 21:01
  • Last Updated by Byron Porter 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#
# 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'
RPT_COL_COST_PER_CONV = 'CLICKS Cost/Conv.'

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_strategy = inputDf[RPT_COL_PUBLISHER_BIDSTRATEGY]

# 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

# define temp dataframes
moreDf = pd.DataFrame()
lessDf = pd.DataFrame()

# Check if campaigns have 5 or more clicks
clicks_check = inputDf[RPT_COL_CLICKS] >= 5

# Use check to create DataFrames for campaigns with and without more than 5 clicks during reporting period
after_fiveDf = inputDf.loc[clicks_check, :].copy()
before_fiveDf = inputDf.loc[~clicks_check, :].copy()


# use boolean expressions to set new values based on Rev/Click and spend thresholds
after_fiveDf.loc[after_fiveDf[RPT_COL_RPC] < 2.75, TMP_STATUS] = 'Pause'
after_fiveDf.loc[after_fiveDf[RPT_COL_RPC] < 2.75, TMP_PUB_STRATEGY] = after_fiveDf[RPT_COL_PUBLISHER_BIDSTRATEGY]
after_fiveDf.loc[after_fiveDf[RPT_COL_RPC] < 2.75, TMP_TARGETCPA] = after_fiveDf[RPT_COL_PUBLISHER_TARGETCPA]

after_fiveDf.loc[after_fiveDf[RPT_COL_RPC] >= 2.75, TMP_STATUS] = after_fiveDf[RPT_COL_CAMPAIGN_STATUS]
after_fiveDf.loc[after_fiveDf[RPT_COL_RPC] >= 2.75, TMP_PUB_STRATEGY] = 'TargetCpa'
after_fiveDf.loc[after_fiveDf[RPT_COL_RPC] >= 2.75, TMP_TARGETCPA] = after_fiveDf[RPT_COL_COST_PER_CONV]

before_fiveDf.loc[before_fiveDf[RPT_COL_PUB_COST] > 50, TMP_STATUS] = 'Pause'
before_fiveDf.loc[before_fiveDf[RPT_COL_PUB_COST] > 50, TMP_PUB_STRATEGY] = before_fiveDf[RPT_COL_PUBLISHER_BIDSTRATEGY]
before_fiveDf.loc[before_fiveDf[RPT_COL_PUB_COST] > 50, TMP_TARGETCPA] = before_fiveDf[RPT_COL_PUBLISHER_TARGETCPA]


print("== Current After Dataframe ==", tableize(after_fiveDf))
print("== Current Before Dataframe ==", tableize(before_fiveDf))

# find changed campaigns for campaigns with 5 or more clicks
changed = (after_fiveDf[TMP_STATUS].notnull() & (after_fiveDf[RPT_COL_CAMPAIGN_STATUS] != after_fiveDf[TMP_STATUS])) | \
          (after_fiveDf[TMP_PUB_STRATEGY].notnull() & (after_fiveDf[RPT_COL_PUBLISHER_BIDSTRATEGY] != after_fiveDf[TMP_PUB_STRATEGY])) | \
          (after_fiveDf[TMP_TARGETCPA].notnull() & (after_fiveDf[RPT_COL_PUBLISHER_TARGETCPA] != after_fiveDf[TMP_TARGETCPA]))

if sum(changed) > 0:

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

    # only select changed rows
    cols = [RPT_COL_ACCOUNT, RPT_COL_CAMPAIGN, TMP_STATUS, TMP_PUB_STRATEGY, TMP_TARGETCPA]
    moreDf = after_fiveDf.loc[ changed, cols ].copy() \
                    .rename(columns = { \
                        TMP_STATUS: BULK_COL_STATUS, \
                        TMP_PUB_STRATEGY: BULK_COL_PUBLISHER_BIDSTRATEGY, \
                        TMP_TARGETCPA: BULK_COL_PUBLISHER_TARGETCPA \
                    })

else:
    
    print("Empty moreDf")
    moreDf = moreDf.iloc[0:0]

# find changed campaigns for campaigns with less than 5 clicks
changed = (before_fiveDf[TMP_STATUS].notnull() & (before_fiveDf[RPT_COL_CAMPAIGN_STATUS] != before_fiveDf[TMP_STATUS])) | \
          (before_fiveDf[TMP_PUB_STRATEGY].notnull() & (before_fiveDf[RPT_COL_PUBLISHER_BIDSTRATEGY] != before_fiveDf[TMP_PUB_STRATEGY])) | \
          (before_fiveDf[TMP_TARGETCPA].notnull() & (before_fiveDf[RPT_COL_PUBLISHER_TARGETCPA] != before_fiveDf[TMP_TARGETCPA]))

if sum(changed) > 0:

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

    # only select changed rows
    cols = [RPT_COL_ACCOUNT, RPT_COL_CAMPAIGN, TMP_STATUS, TMP_PUB_STRATEGY, TMP_TARGETCPA]
    lessDf = before_fiveDf.loc[ changed, cols ].copy() \
                    .rename(columns = { \
                        TMP_STATUS: BULK_COL_STATUS, \
                        TMP_PUB_STRATEGY: BULK_COL_PUBLISHER_BIDSTRATEGY, \
                        TMP_TARGETCPA: BULK_COL_PUBLISHER_TARGETCPA \
                    })

else:
    
    print("Empty lessDf")
    lessDf = lessDf.iloc[0:0]    

# Merge defined data, exlcuding those that are empty, and print the resulting outputDf
dataframes = [moreDf, lessDf]
non_empty_dataframes = [df for df in dataframes if not df.empty]

if non_empty_dataframes:
    outputDf = pd.concat(non_empty_dataframes)
    print("outputDf", tableize(outputDf))
else:
    print("Empty outputDf")
    outputDf = outputDf.iloc[0:0]

Post generated on 2024-05-15 07:44:05 GMT

comments powered by Disqus