GenAICoder commited on
Commit
5b7f9f3
·
verified ·
1 Parent(s): 3a1ddab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +144 -23
app.py CHANGED
@@ -62,19 +62,44 @@ def run_acquisition_analysis(
62
 
63
  if analysis_type == "Mix Analysis":
64
 
65
- result = calculate_vintage_mix(
66
- df=acq,
67
- vintage_col="booking_vintage",
68
- group_col=dimension
 
 
 
 
 
69
  )
70
 
 
 
 
 
 
 
 
 
 
 
 
71
  result = result.rename(
72
  columns={
73
- "accounts": "count"
 
74
  }
75
  )
76
 
77
- return result
 
 
 
 
 
 
 
 
78
 
79
  # ----------------------------------------
80
  # LIMIT ANALYSIS
@@ -93,9 +118,36 @@ def run_acquisition_analysis(
93
  .reset_index()
94
  )
95
 
96
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
  else:
 
99
  return pd.DataFrame()
100
 
101
 
@@ -136,7 +188,7 @@ def run_performance_analysis(
136
  )
137
 
138
  # ----------------------------------------
139
- # STANDARDIZED OUTPUT FORMAT
140
  # ----------------------------------------
141
 
142
  metric_col = [
@@ -144,6 +196,10 @@ def run_performance_analysis(
144
  if "rate" in col.lower()
145
  ][0]
146
 
 
 
 
 
147
  if group_col is not None:
148
 
149
  final_result = result.rename(
@@ -163,20 +219,43 @@ def run_performance_analysis(
163
 
164
  final_result["segment"] = "Overall"
165
 
166
- # Add dummy balance column for consistency
167
- # Later replace with actual exposure logic
 
168
 
169
- final_result["balance"] = None
 
 
 
 
 
170
 
171
- final_result = final_result[
172
- [
173
- "booking_vintage",
174
- "segment",
175
- "total_accounts",
176
- "balance",
177
- "rate"
178
- ]
179
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
  final_result = final_result.rename(
182
  columns={
@@ -185,7 +264,23 @@ def run_performance_analysis(
185
  }
186
  )
187
 
188
- return final_result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
 
191
  # ---------------------------------------------------
@@ -196,6 +291,10 @@ def update_analysis_dropdown(
196
  dataset_type
197
  ):
198
 
 
 
 
 
199
  if dataset_type == "Acquisition":
200
 
201
  return gr.update(
@@ -206,6 +305,10 @@ def update_analysis_dropdown(
206
  value="Mix Analysis"
207
  )
208
 
 
 
 
 
209
  elif dataset_type == "Performance":
210
 
211
  return gr.update(
@@ -223,6 +326,10 @@ def update_dimension_dropdown(
223
  dataset_type
224
  ):
225
 
 
 
 
 
226
  if dataset_type == "Acquisition":
227
 
228
  return gr.update(
@@ -235,6 +342,10 @@ def update_dimension_dropdown(
235
  value="sourcing_channel"
236
  )
237
 
 
 
 
 
238
  elif dataset_type == "Performance":
239
 
240
  return gr.update(
@@ -308,12 +419,22 @@ with gr.Blocks() as app:
308
  )
309
 
310
  analysis_selection = gr.Dropdown(
311
- choices=[],
 
 
 
 
312
  label="Analysis"
313
  )
314
 
315
  dimension_selection = gr.Dropdown(
316
- choices=[],
 
 
 
 
 
 
317
  label="Dimension"
318
  )
319
 
 
62
 
63
  if analysis_type == "Mix Analysis":
64
 
65
+ result = (
66
+ acq.groupby(
67
+ ["booking_vintage", dimension]
68
+ )
69
+ .agg(
70
+ count=("account_id", "nunique"),
71
+ balance=("credit_limit", "sum")
72
+ )
73
+ .reset_index()
74
  )
75
 
76
+ vintage_total = (
77
+ result.groupby("booking_vintage")["count"]
78
+ .transform("sum")
79
+ )
80
+
81
+ result["rate"] = (
82
+ result["count"] / vintage_total
83
+ ) * 100
84
+
85
+ result["rate"] = result["rate"].round(2)
86
+
87
  result = result.rename(
88
  columns={
89
+ "booking_vintage": "vintage",
90
+ dimension: "segment"
91
  }
92
  )
93
 
94
+ return result[
95
+ [
96
+ "vintage",
97
+ "segment",
98
+ "count",
99
+ "balance",
100
+ "rate"
101
+ ]
102
+ ]
103
 
104
  # ----------------------------------------
105
  # LIMIT ANALYSIS
 
118
  .reset_index()
119
  )
120
 
121
+ vintage_total = (
122
+ result.groupby("booking_vintage")["balance"]
123
+ .transform("sum")
124
+ )
125
+
126
+ result["rate"] = (
127
+ result["balance"] / vintage_total
128
+ ) * 100
129
+
130
+ result["rate"] = result["rate"].round(2)
131
+
132
+ result = result.rename(
133
+ columns={
134
+ "booking_vintage": "vintage",
135
+ dimension: "segment"
136
+ }
137
+ )
138
+
139
+ return result[
140
+ [
141
+ "vintage",
142
+ "segment",
143
+ "count",
144
+ "balance",
145
+ "rate"
146
+ ]
147
+ ]
148
 
149
  else:
150
+
151
  return pd.DataFrame()
152
 
153
 
 
188
  )
189
 
190
  # ----------------------------------------
191
+ # IDENTIFY METRIC COLUMN
192
  # ----------------------------------------
193
 
194
  metric_col = [
 
196
  if "rate" in col.lower()
197
  ][0]
198
 
199
+ # ----------------------------------------
200
+ # STANDARDIZED OUTPUT
201
+ # ----------------------------------------
202
+
203
  if group_col is not None:
204
 
205
  final_result = result.rename(
 
219
 
220
  final_result["segment"] = "Overall"
221
 
222
+ # ----------------------------------------
223
+ # BALANCE LOGIC
224
+ # ----------------------------------------
225
 
226
+ # Delinquency metrics
227
+ if metric_name in [
228
+ "30+@3",
229
+ "30+@6",
230
+ "60+@6"
231
+ ]:
232
 
233
+ if "bad_balance" in final_result.columns:
234
+
235
+ final_result["balance"] = (
236
+ final_result["bad_balance"]
237
+ )
238
+
239
+ else:
240
+
241
+ final_result["balance"] = None
242
+
243
+ # NCL metric
244
+ elif metric_name == "Yr1 NCL":
245
+
246
+ if "total_balance" in final_result.columns:
247
+
248
+ final_result["balance"] = (
249
+ final_result["total_balance"]
250
+ )
251
+
252
+ else:
253
+
254
+ final_result["balance"] = None
255
+
256
+ # ----------------------------------------
257
+ # FINAL OUTPUT FORMAT
258
+ # ----------------------------------------
259
 
260
  final_result = final_result.rename(
261
  columns={
 
264
  }
265
  )
266
 
267
+ required_cols = [
268
+ "vintage",
269
+ "segment",
270
+ "count",
271
+ "balance",
272
+ "rate"
273
+ ]
274
+
275
+ for col in required_cols:
276
+
277
+ if col not in final_result.columns:
278
+
279
+ final_result[col] = None
280
+
281
+ return final_result[
282
+ required_cols
283
+ ]
284
 
285
 
286
  # ---------------------------------------------------
 
291
  dataset_type
292
  ):
293
 
294
+ # ----------------------------------------
295
+ # ACQUISITION
296
+ # ----------------------------------------
297
+
298
  if dataset_type == "Acquisition":
299
 
300
  return gr.update(
 
305
  value="Mix Analysis"
306
  )
307
 
308
+ # ----------------------------------------
309
+ # PERFORMANCE
310
+ # ----------------------------------------
311
+
312
  elif dataset_type == "Performance":
313
 
314
  return gr.update(
 
326
  dataset_type
327
  ):
328
 
329
+ # ----------------------------------------
330
+ # ACQUISITION
331
+ # ----------------------------------------
332
+
333
  if dataset_type == "Acquisition":
334
 
335
  return gr.update(
 
342
  value="sourcing_channel"
343
  )
344
 
345
+ # ----------------------------------------
346
+ # PERFORMANCE
347
+ # ----------------------------------------
348
+
349
  elif dataset_type == "Performance":
350
 
351
  return gr.update(
 
419
  )
420
 
421
  analysis_selection = gr.Dropdown(
422
+ choices=[
423
+ "Mix Analysis",
424
+ "Limit Analysis"
425
+ ],
426
+ value="Mix Analysis",
427
  label="Analysis"
428
  )
429
 
430
  dimension_selection = gr.Dropdown(
431
+ choices=[
432
+ "sourcing_channel",
433
+ "fico_band",
434
+ "city_tier",
435
+ "occupation_type"
436
+ ],
437
+ value="sourcing_channel",
438
  label="Dimension"
439
  )
440