samkeet commited on
Commit
cde80d3
·
verified ·
1 Parent(s): 70a3099

First Commit

Browse files
Files changed (49) hide show
  1. .gitattributes +39 -35
  2. ALDI_2017.png +0 -0
  3. Full_Logo_Blue.png +0 -0
  4. Full_Logo_Vibrant_Turquoise.png +0 -0
  5. Media_data_for_model.csv +182 -0
  6. Media_data_for_model_dma_level.csv +538 -0
  7. Model_Result_Overview.py +398 -0
  8. Overview_data_test.xlsx +0 -0
  9. Overview_data_test_panel@#prospects.xlsx +0 -0
  10. README.md +12 -12
  11. Scenario.py +338 -0
  12. Streamlit_functions.py +1659 -0
  13. Test/X_test_tuned_trend.csv +971 -0
  14. Test/X_train_test_tuned_trend.csv +0 -0
  15. Test/X_train_tuned_trend.csv +0 -0
  16. Test/merged_df_contri.csv +0 -0
  17. Test/output_df.csv +105 -0
  18. Test/scenario_test_df.csv +105 -0
  19. Test/x_test_contribution.csv +0 -0
  20. Test/x_test_to_save.csv +0 -0
  21. Test/x_train_contribution.csv +0 -0
  22. Test/x_train_to_save.csv +0 -0
  23. Transformation_functions.py +133 -0
  24. all_solutions_2024-05-09.json +148 -0
  25. classes.py +698 -0
  26. config.yaml +13 -0
  27. data_import.pkl +3 -0
  28. data_test_overview_panel_#total_approved_accounts_revenue.xlsx +0 -0
  29. enviroment.yml +11 -0
  30. final_df_transformed.pkl +3 -0
  31. image (2).png +0 -0
  32. input_data_example.xlsx +0 -0
  33. metrics_level_data/Overview_data_test.xlsx +0 -0
  34. metrics_level_data/Overview_data_test_panel@#revenue.xlsx +0 -0
  35. pages/1_Model_Quality.py +189 -0
  36. pages/2_Scenario_Planner.py +0 -0
  37. pages/3_Saved_Scenarios.py +616 -0
  38. pages/5_Glossary.py +36 -0
  39. requirements.txt +96 -0
  40. response_curves_input_file.csv +106 -0
  41. response_curves_model_quality.py +506 -0
  42. response_curves_model_quality_base.py +283 -0
  43. response_curves_parameters.xlsx +0 -0
  44. setup.sh +8 -0
  45. styles.css +88 -0
  46. summary_df.pkl +3 -0
  47. tuned_model.pkl +3 -0
  48. utilities.py +796 -0
  49. utilities_with_panel.py +1025 -0
.gitattributes CHANGED
@@ -1,35 +1,39 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ Pickle_files/main_df filter=lfs diff=lfs merge=lfs -text
37
+ upf_data_converted_old.xlsx filter=lfs diff=lfs merge=lfs -text
38
+ upf_data_converted_randomized_resp_metrics.xlsx filter=lfs diff=lfs merge=lfs -text
39
+ upf_data_converted.xlsx filter=lfs diff=lfs merge=lfs -text
ALDI_2017.png ADDED
Full_Logo_Blue.png ADDED
Full_Logo_Vibrant_Turquoise.png ADDED
Media_data_for_model.csv ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,paid_search_impressions,paid_search_clicks,kwai_impressions,kwai_clicks,programmaticimpressions,programmaticclicks,affiliates_impressions,affiliates_clicks,indicacao_impressions,indicacao_clicks,infleux_impressions,infleux_clicks,influencer_impressions,influencer_clicks,Total Approved Accounts - Revenue,FB: Level Achieved - Tier 1 Impressions, FB: Level Achieved - Tier 2 Impressions,paid_social_others, GA App: Will And Cid Pequena Baixo Risco Clicks,digital_tactic_others
2
+ 2023-05-09,6111,1916,1365036.0,5044.0,104781,31371909,0,3341,0,11190,0,61956,0,457,5066400,2371841.0,1021599.0,2302543.0,34816.0,19205.0
3
+ 2023-05-10,6233,1888,1234034.0,3899.0,140810,32973036,0,3214,0,9988,0,52049,0,705,5480000,2100238.0,943808.0,2336369.0,19716.0,17415.0
4
+ 2023-05-11,5568,1816,1016155.0,2788.0,102248,50729517,0,3203,0,10869,0,8042,0,381,4133100,2461265.0,1127717.0,1110415.0,21547.0,11051.0
5
+ 2023-05-12,5109,1769,1228032.0,3101.0,100246,63142114,0,2492,0,7096,0,10596,0,299,3573910,2313368.0,1107256.0,1191901.0,31966.0,11081.0
6
+ 2023-05-13,3712,1231,1344557.0,3399.0,100714,59509032,0,3986,0,4282,0,9753,0,366,2776120,3067797.0,1388882.0,1403486.0,38518.0,10762.0
7
+ 2023-05-14,3719,1241,1520157.0,3491.0,120162,49538293,0,1891,0,3002,0,7363,0,278,2611960,3140882.0,1429620.0,2518831.0,44744.0,12151.0
8
+ 2023-05-15,7735,2663,2102264.0,5175.0,106903,46609819,0,2518,0,4548,0,16201,0,880,3951760,2916228.0,1288902.0,2456845.0,36269.0,15290.0
9
+ 2023-05-16,9409,3206,2134290.0,5636.0,88201,9662393,0,2247,0,6690,0,15031,0,1588,4150900,3161940.0,1370882.0,2403330.0,37393.0,14187.0
10
+ 2023-05-17,8409,2785,1473128.0,4336.0,56382,2232239,0,2557,0,6401,0,8946,0,322,3788540,3199527.0,1379566.0,2608845.0,39190.0,12591.0
11
+ 2023-05-18,8364,2873,1733275.0,5009.0,38145,7321146,0,2912,0,7286,0,14366,0,660,3652210,2623727.0,1115471.0,1723470.0,36020.0,12100.0
12
+ 2023-05-19,6432,2050,1784426.0,5063.0,23340,8715910,0,3934,0,6035,0,20378,0,362,3777590,2995998.0,1287313.0,1959870.0,36885.0,12848.0
13
+ 2023-05-20,5428,1724,1635604.0,4408.0,34693,8783612,0,3318,0,4714,0,21030,0,236,3437270,2996479.0,1326416.0,1903323.0,31048.0,12256.0
14
+ 2023-05-21,5657,1807,1788487.0,4492.0,24812,5015214,0,2253,0,4227,0,11656,0,494,3020020,3167634.0,1309450.0,3651254.0,33361.0,13073.0
15
+ 2023-05-22,5768,2036,2176947.0,5688.0,25298,3002995,0,2739,0,8313,0,25663,0,1147,3643240,3573865.0,1548365.0,3939226.0,33410.0,14092.0
16
+ 2023-05-23,5051,1720,2359219.0,6966.0,24773,3005057,0,4738,0,13827,0,47900,0,965,5146270,3248157.0,1376975.0,3631390.0,35016.0,13025.0
17
+ 2023-05-24,6078,1977,1612918.0,4924.0,24591,2833280,0,4816,0,12417,0,94489,0,1254,5832220,3572793.0,1550315.0,3532105.0,37491.0,12546.0
18
+ 2023-05-25,6547,2075,1468456.0,3624.0,19705,2771412,0,5070,0,7395,0,70016,0,762,5217860,3164337.0,1353382.0,3253308.0,34658.0,13154.0
19
+ 2023-05-26,3719,1189,1770048.0,4874.0,16879,2875657,0,2855,0,6964,0,29015,0,627,4123930,2989794.0,1248779.0,3345390.0,38267.0,12788.0
20
+ 2023-05-27,3620,1145,1900387.0,5061.0,14156,2663378,0,3295,0,4472,0,5625,0,1473,2668440,3576647.0,1527545.0,3694843.0,40685.0,12844.0
21
+ 2023-05-28,4195,1302,2026053.0,5703.0,12334,2609966,0,2190,0,3737,0,5030,0,1401,2630380,3376177.0,1447089.0,2563297.0,42359.0,13543.0
22
+ 2023-05-29,5265,1798,2328823.0,6483.0,14783,2537637,0,3954,0,5211,0,221,0,1575,3057510,3765997.0,1720747.0,2865333.0,39579.0,8116.0
23
+ 2023-05-30,3879,1366,2294654.0,6008.0,15979,2489630,0,4465,0,6041,0,6,0,1192,3360270,3790830.0,1751416.0,2822819.0,37234.0,8830.0
24
+ 2023-05-31,3933,1348,1645187.0,4081.0,14208,2337652,0,3797,0,4794,0,6,0,888,3158130,4151434.0,1953620.0,2714074.0,45856.0,6861.0
25
+ 2023-06-01,4817,1530,1862175.0,4841.0,48192,3241822,0,3060,0,4802,0,12820,0,1137,3322330,4151797.0,1903421.0,2255850.0,51175.0,7095.0
26
+ 2023-06-02,5733,1800,966546.0,2646.0,43573,4582872,0,1563,0,10678,0,46810,0,1309,4244170,4313201.0,2009602.0,2074692.0,47378.0,6120.0
27
+ 2023-06-03,4142,1290,2445721.0,11111.0,90587,4764628,0,2176,0,5144,0,27735,0,518,3711670,4514302.0,2083217.0,2095544.0,58527.0,5748.0
28
+ 2023-06-04,5143,1613,2296690.0,6790.0,40929,4717779,0,1280,0,4237,0,5606,0,325,2851980,4179140.0,1889452.0,2152476.0,45239.0,6093.0
29
+ 2023-06-05,5384,1832,3509278.0,8938.0,56272,19979584,0,1377,0,11493,0,25647,0,579,4117320,3683204.0,1641254.0,3616732.0,40356.0,6453.0
30
+ 2023-06-06,4802,1594,3216944.0,7861.0,20049,33102789,0,1485,0,9086,0,36532,0,545,4627290,3822453.0,1716540.0,3687300.0,53347.0,6334.0
31
+ 2023-06-07,5072,1648,2143372.0,5356.0,22553,21321547,0,1576,0,7213,0,21215,0,628,4019320,4178339.0,1811963.0,2354753.0,51632.0,6259.0
32
+ 2023-06-08,4444,1465,3190766.0,8024.0,53653,10254268,0,2046,0,10491,0,19549,0,769,4272770,3941272.0,1738344.0,2283350.0,59291.0,6775.0
33
+ 2023-06-09,4818,1605,3278715.0,9328.0,18347,4890758,0,1925,0,8360,0,32385,0,1732,4788710,3969227.0,1777864.0,2353376.0,52000.0,6026.0
34
+ 2023-06-10,3465,1207,2887842.0,8529.0,725,5489947,0,1230,0,5401,0,37954,0,2136,4707070,4458593.0,2061762.0,2535928.0,66567.0,5554.0
35
+ 2023-06-11,4727,1501,3149290.0,8114.0,738,5313957,0,1839,0,8198,0,32493,0,1533,4560170,4442610.0,2006438.0,2183963.0,47655.0,6008.0
36
+ 2023-06-12,6437,2208,4416005.0,12345.0,149561,5298884,0,1905,0,8542,0,101079,0,472,7031980,4645531.0,1995891.0,3301882.0,38760.0,4966.0
37
+ 2023-06-13,3556,1254,4626697.0,12984.0,258088,5952266,0,2095,0,10415,0,59770,0,1016,5335600,4508060.0,1912958.0,3440789.0,47281.0,4630.0
38
+ 2023-06-14,3178,1060,3389530.0,10298.0,685692,10454400,0,2258,0,24457,0,16016,0,1101,4382390,4573214.0,1920050.0,3160905.0,41549.0,5083.0
39
+ 2023-06-15,2981,999,3131350.0,10791.0,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4334320,4075106.0,1690702.0,3267810.0,50496.0,5037.0
40
+ 2023-06-16,2705,947,2923279.0,11124.0,1166424,11840950,0,1780,0,8938,0,24339,0,966,4560830,4533368.0,1939737.0,2881833.0,41872.0,4604.0
41
+ 2023-06-17,3697,1154,2955836.0,10440.0,807683,9748201,0,2139,0,5741,0,54129,0,766,4890110,4958344.0,2059487.0,3183051.0,52618.0,3675.0
42
+ 2023-06-18,3229,1080,3280006.0,12373.0,116340,8176712,0,1481,0,4741,0,16724,0,864,3388060,4270249.0,1735486.0,3251229.0,39780.0,3696.0
43
+ 2023-06-19,3082,1003,6545797.0,24462.0,55763,4841897,0,2098,0,10520,0,26558,0,2211,4639400,4137846.0,1743715.0,2680413.0,43156.0,4347.0
44
+ 2023-06-20,2422,857,6734594.0,28910.0,52166,4718912,0,2205,0,10284,0,30610,0,1002,4969720,4218772.0,1771102.0,2058734.0,42288.0,4260.0
45
+ 2023-06-21,3366,1132,4784180.0,17247.0,52817,5971594,0,3387,0,9277,0,41697,0,645,4489250,4113884.0,1743016.0,2111350.0,44159.0,4193.0
46
+ 2023-06-22,2841,924,3300680.0,13360.0,29784,6803330,0,4064,0,7068,0,68638,0,481,5006920,3738171.0,1533407.0,1597072.0,35381.0,4173.0
47
+ 2023-06-23,2474,805,2284446.0,9012.0,80066,6833289,0,3274,0,7379,0,13501,0,721,3069350,4479743.0,1889155.0,1647740.0,39089.0,3640.0
48
+ 2023-06-24,2462,814,1947190.0,7247.0,50309,6526903,0,2767,0,4703,0,8438,0,616,2776800,3758421.0,1565736.0,1648519.0,46332.0,3834.0
49
+ 2023-06-25,2082,679,3560248.0,14850.0,50806,6368664,0,2767,0,4414,0,5346,0,628,2860440,4038846.0,1700182.0,2514456.0,43065.0,4201.0
50
+ 2023-06-26,2399,839,5999950.0,28401.0,23209,10788275,0,3699,0,13383,0,13592,0,790,3928490,3427918.0,1403888.0,3598236.0,33883.0,4642.0
51
+ 2023-06-27,2307,804,5005495.0,18260.0,81344,14103220,0,7082,0,8898,0,40917,0,945,5851320,3819654.0,1523667.0,3556028.0,35326.0,4628.0
52
+ 2023-06-28,2215,759,3721084.0,11248.0,20153,10547995,0,8387,0,7120,0,39693,0,944,6083570,3671994.0,1568555.0,1397196.0,33212.0,2998.0
53
+ 2023-06-29,2013,706,3918049.0,10226.0,155296,8525871,0,10096,0,5693,0,24049,0,1512,4328260,3937747.0,1585655.0,3393043.0,30700.0,2519.0
54
+ 2023-06-30,1258,454,3088874.0,7943.0,902115,10945715,0,8904,0,9611,0,62404,0,1029,5252540,4945464.0,1946944.0,1835310.0,52445.0,2839.0
55
+ 2023-07-01,1641,539,3872657.0,12034.0,191537,12141356,0,4956,0,6049,0,31194,0,923,4626340,5328149.0,2224200.0,2123805.0,56724.0,2513.0
56
+ 2023-07-02,1336,485,5799582.0,17238.0,576858,12180985,0,4148,0,4670,0,4766,0,617,3416990,4527404.0,1997256.0,2038953.0,50510.0,21201.0
57
+ 2023-07-03,2712,924,9986061.0,28191.0,442261,14059535,0,5347,0,7408,0,19028,0,1044,4925290,4179823.0,1854231.0,2234940.0,57543.0,14473.0
58
+ 2023-07-04,4137,1419,4717456.0,14519.0,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4394760,4449073.0,1959412.0,2350308.0,49085.0,9854.0
59
+ 2023-07-05,4166,1422,4779589.0,12676.0,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4497600,4464681.0,1969744.0,2390838.0,41411.0,12751.0
60
+ 2023-07-06,4182,1444,4939385.0,12222.0,2364811,15879491,0,6575,0,8461,0,18225,0,997,5114750,4490815.0,1942923.0,2239375.0,44808.0,16216.0
61
+ 2023-07-07,3497,1181,3121447.0,7534.0,1063284,17341347,0,6025,0,8113,0,25962,0,659,4910810,4891573.0,2128787.0,1976413.0,57373.0,12464.0
62
+ 2023-07-08,2760,856,3295227.0,9788.0,1119268,19207341,0,4102,0,6195,0,40506,0,832,4471260,5039604.0,2277255.0,2330435.0,44052.0,15163.0
63
+ 2023-07-09,2809,875,3913741.0,11815.0,749310,25182206,0,6420,0,5222,0,49626,0,718,5706060,4669470.0,2144473.0,3908306.0,49659.0,11716.0
64
+ 2023-07-10,4312,1489,5972974.0,18402.0,1511035,25950979,0,9842,0,10638,0,36204,0,935,5299330,4584106.0,2019220.0,4391654.0,52303.0,12983.0
65
+ 2023-07-11,4579,1550,4999618.0,16469.0,559119,23938153,0,11688,0,36570,0,25216,0,1289,5532390,4458364.0,1932300.0,4150666.0,47979.0,12292.0
66
+ 2023-07-12,4079,1418,4465722.0,13191.0,583520,25196511,0,4610,0,9813,0,20388,0,1210,5067480,4558876.0,2000168.0,4109583.0,54631.0,12366.0
67
+ 2023-07-13,3719,1260,4635033.0,12302.0,903614,25720336,0,7867,0,6792,0,22248,0,857,4393760,4596184.0,1957206.0,3729970.0,48474.0,11017.0
68
+ 2023-07-14,3632,1224,3441594.0,9800.0,1566300,28606996,0,6726,0,6172,0,14670,0,432,3983150,4683387.0,2007387.0,3912229.0,52588.0,10079.0
69
+ 2023-07-15,2909,941,6025085.0,21326.0,1836196,28705476,0,5705,0,4369,0,31202,0,595,4220310,5008167.0,2251661.0,3727627.0,58143.0,10214.0
70
+ 2023-07-16,2818,853,7339565.0,26586.0,4043959,26752554,0,7733,0,3961,0,27180,0,1082,3832400,4716541.0,2092258.0,2114014.0,59204.0,11281.0
71
+ 2023-07-17,4420,1486,9638491.0,32269.0,819444,29437537,0,11485,0,5220,0,66236,0,2418,5691990,4359325.0,1937825.0,1989872.0,55815.0,11896.0
72
+ 2023-07-18,4574,1551,9498457.0,31230.0,1206114,29164369,0,5012,0,7146,0,47074,0,2358,5347820,4882304.0,2163458.0,2157773.0,69573.0,12604.0
73
+ 2023-07-19,4632,1537,9742535.0,26935.0,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4690310,4613422.0,2080215.0,1981362.0,67495.0,12116.0
74
+ 2023-07-20,4891,1632,7630122.0,20720.0,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4576570,4484291.0,1922090.0,1663127.0,75312.0,12252.0
75
+ 2023-07-21,3978,1378,7284968.0,21477.0,2456715,17869335,0,6360,0,10877,0,11431,0,769,4357960,4519305.0,1975730.0,1686467.0,68931.0,10065.0
76
+ 2023-07-22,3151,978,5638955.0,16181.0,2015345,12808440,0,7097,0,5145,0,13811,0,699,3959970,4689346.0,2086993.0,1861883.0,71898.0,9081.0
77
+ 2023-07-23,2905,986,6133144.0,16089.0,881691,11267535,0,5593,0,4746,0,68021,0,514,5284400,4242878.0,1843843.0,1681215.0,61164.0,10797.0
78
+ 2023-07-24,4606,1651,8830736.0,21931.0,189913,35658281,0,8836,0,6040,0,64066,0,1626,6253530,3943001.0,1708849.0,1900126.0,59494.0,10236.0
79
+ 2023-07-25,4414,1597,7750251.0,15384.0,3348941,25011847,0,10262,0,9572,0,15072,0,916,4938210,3976490.0,1729916.0,1911109.0,68826.0,11468.0
80
+ 2023-07-26,4488,1530,8125332.0,16391.0,1040452,24380635,0,9947,0,16453,0,38777,0,1551,5687460,3837786.0,1680967.0,1856885.0,74924.0,13290.0
81
+ 2023-07-27,4105,1494,8054962.0,14724.0,220302,13070502,0,6758,0,8841,0,20622,0,1313,5138270,3636297.0,1544742.0,1772602.0,63935.0,11680.0
82
+ 2023-07-28,3743,1318,6955526.0,11566.0,3991586,5347413,0,10451,0,8496,0,20184,0,1563,4621140,3890784.0,1680538.0,1608577.0,73120.0,11390.0
83
+ 2023-07-29,3395,1192,5132501.0,9837.0,1349895,4441709,0,7115,0,5449,0,18983,0,1129,3893270,4295602.0,1813637.0,1824777.0,80511.0,11911.0
84
+ 2023-07-30,2746,903,4903153.0,11018.0,710000,4431986,0,8491,0,4599,0,24834,0,1109,4020490,3924352.0,1733790.0,1740605.0,72221.0,11440.0
85
+ 2023-07-31,4208,1476,6832832.0,19648.0,1721973,4079656,0,7754,0,7818,0,27918,0,2050,4709550,3760475.0,1501134.0,1957900.0,62124.0,11605.0
86
+ 2023-08-01,4203,1489,6398210.0,15890.0,2250090,5457683,0,7588,0,7948,0,61894,0,1248,5602170,3687038.0,1439092.0,1774701.0,61448.0,11492.0
87
+ 2023-08-02,4285,1515,5402871.0,14825.0,785167,6582085,0,6079,0,7236,0,79041,0,1345,5992910,3807266.0,1493340.0,2025308.0,54506.0,11515.0
88
+ 2023-08-03,4667,1744,4724924.0,8903.0,1111815,10407793,0,9077,0,7117,0,31714,0,1983,4941800,3797879.0,1479623.0,1718831.0,52587.0,11408.0
89
+ 2023-08-04,4201,1562,3732952.0,9116.0,4574481,10660977,0,8436,0,6970,0,25097,0,1055,4659060,3814852.0,1466211.0,1374674.0,57482.0,10785.0
90
+ 2023-08-05,3080,1110,3310732.0,9884.0,3460283,11580456,0,5735,0,5049,0,5911,0,704,3260640,4048945.0,1601234.0,1442690.0,65158.0,9942.0
91
+ 2023-08-06,2809,979,4153998.0,11663.0,5103054,8381689,0,4868,0,4184,0,28658,0,637,4005470,4040770.0,1250223.0,1844909.0,47698.0,10816.0
92
+ 2023-08-07,3522,1186,3164171.0,10000.0,4137349,8709017,0,6112,0,6640,0,43866,0,1285,5034960,3928811.0,1288638.0,1861166.0,44623.0,11648.0
93
+ 2023-08-08,4111,1495,6020074.0,15008.0,2923076,5012245,0,6684,0,6961,0,12257,0,3038,4235970,3921429.0,1094791.0,2059462.0,48047.0,10379.0
94
+ 2023-08-09,3609,1285,5616011.0,13195.0,2483117,3900778,0,8177,0,6447,0,12774,0,1309,4131270,3322165.0,452000.0,2262292.0,52219.0,11047.0
95
+ 2023-08-10,3872,1330,5270940.0,11342.0,1305507,3614496,0,6927,0,6602,0,21830,0,986,4946040,2868345.0,452896.0,1541791.0,46720.0,10556.0
96
+ 2023-08-11,3673,1257,4485834.0,10445.0,3562053,5521177,0,5810,0,13751,0,5797,0,751,3309470,3242607.0,511016.0,1679989.0,47262.0,10344.0
97
+ 2023-08-12,2744,960,3946512.0,10052.0,4015316,5813616,0,6205,0,10379,0,9890,0,532,3177130,3761072.0,595191.0,1931989.0,54787.0,9210.0
98
+ 2023-08-13,2418,775,5051792.0,11809.0,1869057,6348414,0,4093,0,5187,0,21320,0,399,2953700,3279816.0,503805.0,2171335.0,55136.0,10546.0
99
+ 2023-08-14,3551,1196,4839009.0,11805.0,1765326,3758610,0,6170,0,7226,0,19575,0,706,3873510,2974893.0,427940.0,1822890.0,49127.0,11042.0
100
+ 2023-08-15,3430,1312,6520709.0,24857.0,1792924,1852314,0,6063,0,9302,0,34681,0,778,4412810,3080012.0,462344.0,1935145.0,57900.0,11083.0
101
+ 2023-08-16,3253,1175,4844378.0,27290.0,3478033,1293346,0,5884,0,8280,0,29077,0,1055,4074580,3150093.0,468159.0,2094524.0,58937.0,11823.0
102
+ 2023-08-17,3714,1417,4702754.0,23408.0,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3587780,3071572.0,444690.0,1961293.0,58681.0,10987.0
103
+ 2023-08-18,1936,710,4370177.0,18919.0,3789636,1020973,0,9525,0,8958,0,32346,0,909,3722530,3252966.0,461174.0,2031390.0,61098.0,10354.0
104
+ 2023-08-19,1998,723,3683868.0,14860.0,5187185,1336224,0,8305,0,6265,0,13396,0,1267,2943410,3460234.0,494225.0,2037289.0,68988.0,9709.0
105
+ 2023-08-20,2458,839,5558511.0,16917.0,6444084,1333600,0,8083,0,5668,0,9425,0,593,2640290,3233047.0,427550.0,2093935.0,58698.0,11658.0
106
+ 2023-08-21,2316,892,5802540.0,21997.0,1578062,1099659,0,9057,0,8434,0,11204,0,597,3510210,3110596.0,442523.0,1991499.0,71910.0,13059.0
107
+ 2023-08-22,2208,845,5006504.0,13886.0,598218,939529,0,18631,0,11119,0,18304,0,666,3877380,3020862.0,419659.0,1960342.0,66769.0,12591.0
108
+ 2023-08-23,2104,821,5240143.0,16309.0,1941212,2081327,0,17073,0,8077,0,6042,0,709,3219310,2634348.0,409468.0,1726842.0,53998.0,13783.0
109
+ 2023-08-24,2011,685,5623870.0,14314.0,380971,2132605,0,13223,0,7340,0,11449,0,1774,3474730,2244344.0,385012.0,1409286.0,55699.0,13185.0
110
+ 2023-08-25,1889,680,4674166.0,13506.0,1119189,1818097,0,33200,0,7250,0,16577,0,3622,4003360,2405697.0,395219.0,1564070.0,61103.0,13348.0
111
+ 2023-08-26,1229,379,5475213.0,18030.0,476090,1048919,0,15316,0,4976,0,16625,0,3546,3448630,2662312.0,434769.0,1789446.0,61768.0,13346.0
112
+ 2023-08-27,1333,486,5591938.0,13138.0,956722,732493,0,12952,0,4227,0,19562,0,2354,3032970,2470188.0,417919.0,1980888.0,53707.0,14151.0
113
+ 2023-08-28,2031,760,7120359.0,17304.0,592505,571748,0,44816,0,8728,0,19999,0,3813,3941750,2357294.0,420574.0,1878047.0,50335.0,13442.0
114
+ 2023-08-29,1560,550,6349650.0,18074.0,395464,276869,0,217642,0,8742,0,36555,0,2778,4403680,2437012.0,455532.0,1707585.0,52913.0,12648.0
115
+ 2023-08-30,1788,623,6774580.0,17019.0,804715,227676,0,92490,0,7576,0,33376,0,1815,4493600,2461827.0,452647.0,1924554.0,57945.0,12244.0
116
+ 2023-08-31,2251,790,6881955.0,16586.0,462096,216142,0,177608,0,7188,0,13212,0,1862,3467310,2630688.0,508779.0,1691540.0,44071.0,12093.0
117
+ 2023-09-01,2763,930,5360505.0,17680.0,259775,323504,0,21865,0,7383,0,4899,0,1313,2588380,2723715.0,529388.0,1841032.0,48663.0,11275.0
118
+ 2023-09-02,2597,870,4478842.0,15289.0,1226680,320820,0,26924,0,6477,0,4896,0,1454,2531920,2929332.0,613163.0,1945160.0,60288.0,10815.0
119
+ 2023-09-03,2332,762,5174329.0,13994.0,449228,288375,0,20423,0,5755,0,10890,0,1494,2747410,2516381.0,558353.0,1697712.0,54329.0,11996.0
120
+ 2023-09-04,3561,1229,5334952.0,17444.0,296660,306771,0,324815,0,7849,0,41134,0,2069,3987700,2485534.0,613680.0,1823512.0,52578.0,12787.0
121
+ 2023-09-05,2261,816,6113505.0,20426.0,302910,227998,0,287642,0,7998,0,21025,0,1448,3377390,2453507.0,595873.0,1648165.0,49590.0,11749.0
122
+ 2023-09-06,2868,1031,5558783.0,13407.0,1266416,255848,0,203777,0,8887,0,9020,0,933,2814330,2766708.0,736889.0,1987155.0,47189.0,10851.0
123
+ 2023-09-07,2394,832,4907653.0,9041.0,191893,285511,0,202017,0,8317,0,6879,0,801,2893090,2616416.0,630668.0,1712157.0,47089.0,11632.0
124
+ 2023-09-08,2689,910,4752031.0,8867.0,157343,302141,0,201772,0,8717,0,5684,0,1428,2858250,2705167.0,791338.0,1852090.0,43707.0,10493.0
125
+ 2023-09-09,2204,752,3975657.0,10022.0,227113,245700,0,201776,0,7299,0,4098,0,758,2717380,2929279.0,827015.0,2001938.0,50033.0,10082.0
126
+ 2023-09-10,2167,743,4243960.0,10399.0,270612,291468,0,201256,0,6099,0,8097,0,809,2878400,2352670.0,1241029.0,1966290.0,41767.0,10185.0
127
+ 2023-09-11,3381,1227,4492340.0,10684.0,1192346,154867,0,202476,0,8393,0,6493,0,838,2923700,2573007.0,1455728.0,1830559.0,39596.0,12910.0
128
+ 2023-09-12,2511,884,4936079.0,10015.0,199137,170680,0,50740,0,8506,0,26721,0,1085,4318830,2527461.0,1481401.0,1856155.0,40974.0,11883.0
129
+ 2023-09-13,2143,778,5115564.0,10338.0,292239,238162,0,2408,0,7172,0,36811,0,836,3837560,2621020.0,1580825.0,1962940.0,39948.0,11634.0
130
+ 2023-09-14,2307,798,4859067.0,12717.0,1181194,308251,0,948,0,7404,0,38152,0,1282,3797130,2677877.0,1397139.0,1251585.0,46129.0,10253.0
131
+ 2023-09-15,2467,882,4260164.0,9702.0,399193,291844,0,756,0,6932,0,16060,0,2982,3201640,2751748.0,1416780.0,1269521.0,57909.0,10048.0
132
+ 2023-09-16,2076,687,3350011.0,7707.0,620978,196303,0,663,0,6018,0,9889,0,1188,2843020,3083552.0,1564491.0,1439332.0,61159.0,9435.0
133
+ 2023-09-17,2467,802,4503316.0,11119.0,581720,236009,0,637,0,4814,0,10024,0,2464,2605750,2935930.0,1503370.0,1649587.0,48796.0,10073.0
134
+ 2023-09-18,2910,1024,5568066.0,14302.0,184276,143660,0,888,0,6922,0,10381,0,1767,3209930,2373681.0,1330212.0,1479501.0,51224.0,10488.0
135
+ 2023-09-19,3252,1309,6105220.0,12193.0,208312,187769,0,1464,0,5210,0,8092,0,1504,3291230,2373344.0,1285881.0,1407015.0,40642.0,10547.0
136
+ 2023-09-20,2796,1185,6055420.0,14003.0,291395,272928,0,1077,0,4246,0,10472,0,1830,3121460,2565110.0,1425196.0,1460886.0,48962.0,10318.0
137
+ 2023-09-21,2208,878,5225528.0,8679.0,697480,160425,0,1033,0,6726,0,13928,0,1357,3634580,2686089.0,1447330.0,1236533.0,49940.0,10259.0
138
+ 2023-09-22,1734,783,4373391.0,8141.0,2220006,88968,0,738,0,9534,0,8771,0,1690,3160370,2460283.0,1353647.0,1258771.0,45467.0,9910.0
139
+ 2023-09-23,1190,492,4948823.0,10035.0,2432739,154849,0,702,0,8285,0,4369,0,806,2718390,2740252.0,1531672.0,1407980.0,51747.0,8665.0
140
+ 2023-09-24,1124,496,6239124.0,10744.0,248085,231243,0,477,0,8032,0,8640,0,1449,2680930,2648532.0,1476875.0,1294436.0,36638.0,10410.0
141
+ 2023-09-25,2358,1041,5325249.0,9804.0,251517,447312,0,591,0,11299,0,21103,0,1135,3830560,2371891.0,1333464.0,1222194.0,36894.0,9191.0
142
+ 2023-09-26,2092,994,5361926.0,13223.0,90916,351820,0,910,0,10598,0,27697,0,2803,3971740,2612585.0,1502573.0,1256804.0,33211.0,8893.0
143
+ 2023-09-27,1835,792,4600061.0,14060.0,728920,347014,0,1111,0,8811,0,104094,0,1780,5686340,2488689.0,1390273.0,1203937.0,33935.0,8769.0
144
+ 2023-09-28,1787,807,4114657.0,9434.0,84913,564139,0,279332,0,6975,0,51946,0,2516,4377350,2290090.0,1309586.0,1316086.0,32443.0,8606.0
145
+ 2023-09-29,1513,641,4477584.0,8505.0,211297,372199,0,443,0,4039,0,4466,0,1774,2520650,2429135.0,1379398.0,1425850.0,31700.0,7184.0
146
+ 2023-09-30,1127,478,4089760.0,9316.0,222854,364180,0,517,0,3251,0,13297,0,1425,2765900,1049942.0,435407.0,548780.0,10869.0,4505.0
147
+ 2023-10-01,1021,436,748856.0,2639.0,301970,224135,0,846,0,2731,0,7574,0,962,2069510,935755.0,413098.0,1084400.0,13147.0,5335.0
148
+ 2023-10-02,1673,764,1692932.0,4211.0,387802,237932,0,1564,0,12820,0,9400,0,1463,2321500,877002.0,383352.0,1016934.0,14302.0,5965.0
149
+ 2023-10-03,1516,725,1757367.0,3947.0,568156,171003,0,1739,0,21454,0,5276,0,1640,2455260,833524.0,365270.0,973716.0,14227.0,5936.0
150
+ 2023-10-04,1786,763,1733340.0,3119.0,567654,129402,0,1726,0,15833,0,13543,0,2940,2496730,836392.0,368220.0,1029847.0,13931.0,5864.0
151
+ 2023-10-05,1986,861,1671129.0,3736.0,504268,159069,0,1747,0,24285,0,8234,0,3163,2626960,830805.0,380396.0,476125.0,13399.0,5529.0
152
+ 2023-10-06,1774,753,1348401.0,2784.0,702326,205479,0,1686,0,15228,0,12269,0,2107,2378150,817142.0,382879.0,504402.0,11840.0,5476.0
153
+ 2023-10-07,1150,416,1175733.0,2242.0,359848,180366,0,1446,0,19417,0,27951,0,2050,3080590,921412.0,418533.0,520370.0,11215.0,5083.0
154
+ 2023-10-08,999,337,1296701.0,2609.0,662748,293989,0,1415,0,14589,0,18476,0,1786,2484160,768086.0,352949.0,357821.0,12788.0,5550.0
155
+ 2023-10-09,772,289,1942734.0,4167.0,3096792,191352,0,1855,0,24331,0,21658,0,1757,2722910,653538.0,261410.0,590317.0,14449.0,6333.0
156
+ 2023-10-10,737,241,1911227.0,4238.0,565419,164827,0,2101,0,11526,0,9057,0,2720,2528280,734200.0,300476.0,568450.0,13952.0,6145.0
157
+ 2023-10-11,681,256,2171216.0,4714.0,503802,216630,0,1921,0,7255,0,7549,0,2025,2463820,958835.0,399349.0,595481.0,12432.0,5599.0
158
+ 2023-10-12,673,240,1820266.0,4067.0,233553,161215,0,8042,0,4686,0,5288,0,1408,2044540,861845.0,336598.0,557239.0,13130.0,5889.0
159
+ 2023-10-13,595,233,1529402.0,3094.0,68852,156834,0,7184,0,4986,0,14364,0,1924,2576940,801772.0,317596.0,563967.0,12222.0,5539.0
160
+ 2023-10-14,748,266,1013578.0,2156.0,48430,185877,0,3043,0,4287,0,14809,0,2117,2441800,929822.0,362662.0,603684.0,11533.0,5191.0
161
+ 2023-10-15,602,201,1596953.0,4098.0,55580,222305,0,12269,0,4366,0,15778,0,1639,2190130,891052.0,327915.0,425822.0,13301.0,6358.0
162
+ 2023-10-16,964,369,2144206.0,5169.0,31683,118393,0,6488,0,5537,0,65656,0,1254,4509620,842123.0,317951.0,810650.0,16455.0,7813.0
163
+ 2023-10-17,1105,415,2112245.0,5363.0,69479,70676,0,4964,0,4816,0,18719,0,2353,2816530,816941.0,328053.0,766996.0,14912.0,7402.0
164
+ 2023-10-18,913,348,1892230.0,4633.0,451927,111742,0,4068,0,4855,0,32612,0,2028,3728560,957593.0,377866.0,689470.0,15228.0,7272.0
165
+ 2023-10-19,914,302,1550243.0,3817.0,100009,183549,0,4309,0,4468,0,68322,0,2169,4292380,846076.0,336810.0,775970.0,14394.0,6925.0
166
+ 2023-10-20,663,208,1100622.0,2740.0,174916,181797,0,3695,0,4056,0,58835,0,1887,4493840,910115.0,366406.0,653096.0,15447.0,6572.0
167
+ 2023-10-21,559,184,1405730.0,3216.0,207981,276329,0,2723,0,3213,0,44899,0,1893,3204000,1184901.0,485051.0,850250.0,14780.0,6181.0
168
+ 2023-10-22,545,198,1467468.0,3228.0,520836,253840,0,2213,0,2850,0,27411,0,1911,2969510,1154732.0,423852.0,1027954.0,10344.0,4893.0
169
+ 2023-10-23,625,231,2018062.0,5517.0,333114,436011,0,2839,0,3772,0,11121,0,1351,2287750,1208181.0,428535.0,1111507.0,11684.0,6220.0
170
+ 2023-10-24,574,226,1889784.0,5099.0,188275,228582,0,2709,0,2462,0,1109,0,1918,1952480,1083131.0,378488.0,1161439.0,11452.0,5728.0
171
+ 2023-10-25,536,184,2276229.0,5661.0,77308,332105,0,2708,0,2679,0,525,0,2402,1869210,905535.0,310989.0,865636.0,11200.0,5884.0
172
+ 2023-10-26,609,200,1753696.0,4367.0,85971,236204,0,2136,0,2300,0,10,0,3842,1710220,968078.0,332008.0,771447.0,10098.0,5558.0
173
+ 2023-10-27,563,209,1636932.0,3338.0,246909,285904,0,1992,0,2323,0,5,0,2851,1458010,1063329.0,352124.0,929257.0,9507.0,5001.0
174
+ 2023-10-28,450,155,1588245.0,4276.0,235960,324079,0,2716,0,1753,0,1,0,2585,1510690,1191854.0,384343.0,1028724.0,8578.0,4958.0
175
+ 2023-10-29,309,117,1731474.0,5065.0,70210,331208,0,2241,0,1708,0,5,0,3120,1547290,1137463.0,385520.0,764681.0,10186.0,5650.0
176
+ 2023-10-31,486,182,2220653.0,5950.0,41641,213812,0,149,0,2404,0,15,0,1380,1648060,913362.0,318222.0,1020094.0,10416.0,3703.0
177
+ 2023-11-01,296,123,1834772.0,4275.0,201158,313487,0,889,0,2485,0,33093,0,2287,2939670,862276.0,316545.0,798469.0,11740.0,3972.0
178
+ 2023-11-02,346,111,1697213.0,2987.0,1586296,64435,0,957,0,2130,0,16368,0,3586,2385890,840477.0,298617.0,830972.0,10008.0,3641.0
179
+ 2023-11-03,224,89,1759831.0,2940.0,93667,74522,0,962,0,2484,0,14150,0,953,1937810,952592.0,350909.0,800378.0,11090.0,3818.0
180
+ 2023-11-04,214,76,1677064.0,2752.0,65182,61325,0,1796,0,3084,0,10438,0,1148,1622250,957265.0,344580.0,821570.0,11309.0,4380.0
181
+ 2023-11-05,350,100,1553224.0,3167.0,224953,172587,0,727,0,2295,0,17642,0,1535,2117090,,,,,
182
+ 2023-11-06,217,81,718827.0,1492.0,197532,226189,0,8785,0,3391,0,13745,0,1229,2102830,,,,,
Media_data_for_model_dma_level.csv ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,paid_search_impressions,paid_search_clicks,kwai_impressions,kwai_clicks,programmaticimpressions,programmaticclicks,affiliates_impressions,affiliates_clicks,indicacao_impressions,indicacao_clicks,infleux_impressions,infleux_clicks,influencer_impressions,influencer_clicks,FB: Level Achieved - Tier 1 Impressions, FB: Level Achieved - Tier 2 Impressions,paid_social_others, GA App: Will And Cid Pequena Baixo Risco Clicks,digital_tactic_others,DMA,Panel,Account Requests - Appsflyer,App Installs - Appsflyer,BAU approved clients - Appsflyer,BAU approved clients - Revenue,Gamified approved clients - Appsflyer,Gamified approved clients - Revenue,Total Approved Accounts - Appsflyer,Total Approved Accounts - Revenue,Adjusted Account Approval,Adjusted Account Approval BAU
2
+ 9/5/2023,6111,1916,1365036,5044,104781,31371909,0,3341,0,11190,0,61956,0,457,2371841,1021599,2302543,34816,19205,D1,P1,35411,86251,2786,4926900,1395,139500,4181,5066400,6110.89,4301.97
3
+ 10/5/2023,6233,1888,1234034,3899,140810,32973036,0,3214,0,9988,0,52049,0,705,2100238,943808,2336369,19716,17415,D1,P1,37986,96199,3087,5328400,1515,151500,4603,5480000,7186.64,5128.37
4
+ 11/5/2023,5568,1816,1016155,2788,102248,50729517,0,3203,0,10869,0,8042,0,381,2461265,1127717,1110415,21547,11051,D1,P1,24496,77036,2337,4001750,1327,132700,3663,4133100,5892.4,4091.77
5
+ 12/5/2023,5109,1769,1228032,3101,100246,63142114,0,2492,0,7096,0,10596,0,299,2313368,1107256,1191901,31966,11081,D1,P1,21030,75112,2052,3462310,1116,111600,3168,3573910,5091.46,3601.62
6
+ 13/05/2023,3712,1231,1344557,3399,100714,59509032,0,3986,0,4282,0,9753,0,366,3067797,1388882,1403486,38518,10762,D1,P1,16294,64652,1611,2693420,827,82700,2438,2776120,3925.27,2780.04
7
+ 14/05/2023,3719,1241,1520157,3491,120162,49538293,0,1891,0,3002,0,7363,0,278,3140882,1429620,2518831,44744,12151,D1,P1,13378,55706,1428,2535460,765,76500,2193,2611960,3658.41,2543.11
8
+ 15/05/2023,7735,2663,2102264,5175,106903,46609819,0,2518,0,4548,0,16201,0,880,2916228,1288902,2456845,36269,15290,D1,P1,21857,67301,2149,3844360,1075,107500,3223,3951760,5540.69,3945.07
9
+ 16/05/2023,9409,3206,2134290,5636,88201,9662393,0,2247,0,6690,0,15031,0,1588,3161940,1370882,2403330,37393,14187,D1,P1,26562,53380,2486,4026650,1251,125100,3736,4150900,6839.28,4817.99
10
+ 17/05/2023,8409,2785,1473128,4336,56382,2232239,0,2557,0,6401,0,8946,0,322,3199527,1379566,2608845,39190,12591,D1,P1,21930,41033,2100,3675940,1126,112600,3226,3788540,6156.6,4185.47
11
+ 18/05/2023,8364,2873,1733275,5009,38145,7321146,0,2912,0,7286,0,14366,0,660,2623727,1115471,1723470,36020,12100,D1,P1,21813,40251,1987,3528210,1240,124000,3227,3652210,6388.27,4150.71
12
+ 19/05/2023,6432,2050,1784426,5063,23340,8715910,0,3934,0,6035,0,20378,0,362,2995998,1287313,1959870,36885,12848,D1,P1,19874,38360,1888,3663690,1140,114000,3027,3777590,5981.25,3891.85
13
+ 20/05/2023,5428,1724,1635604,4408,34693,8783612,0,3318,0,4714,0,21030,0,236,2996479,1326416,1903323,31048,12256,D1,P1,17568,33060,1691,3342720,931,93100,2623,3437270,5113.91,3453.26
14
+ 21/05/2023,5657,1807,1788487,4492,24812,5015214,0,2253,0,4227,0,11656,0,494,3167634,1309450,3651254,33361,13073,D1,P1,14766,28367,1461,2940020,800,80000,2261,3020020,4874.35,3300.96
15
+ 22/05/2023,5768,2036,2176947,5688,25298,3002995,0,2739,0,8313,0,25663,0,1147,3573865,1548365,3939226,33410,14092,D1,P1,21520,40205,1854,3533540,1097,109700,2951,3643240,6425.41,4211.67
16
+ 23/05/2023,5051,1720,2359219,6966,24773,3005057,0,4738,0,13827,0,47900,0,965,3248157,1376975,3631390,35016,13025,D1,P1,29860,51811,2527,5012370,1339,133900,3866,5146270,7978.08,5238.68
17
+ 24/05/2023,6078,1977,1612918,4924,24591,2833280,0,4816,0,12417,0,94489,0,1254,3572793,1550315,3532105,37491,12546,D1,P1,41297,68099,2993,5666720,1655,165500,4648,5832220,8715.48,5761.11
18
+ 25/05/2023,6547,2075,1468456,3624,19705,2771412,0,5070,0,7395,0,70016,0,762,3164337,1353382,3253308,34658,13154,D1,P1,33436,56714,2588,5066960,1509,150900,4097,5217860,7939.09,5062.98
19
+ 26/05/2023,3719,1189,1770048,4874,16879,2875657,0,2855,0,6964,0,29015,0,627,2989794,1248779,3345390,38267,12788,D1,P1,22185,40261,2101,4010930,1130,113000,3231,4123930,6785.57,4495.67
20
+ 27/05/2023,3620,1145,1900387,5061,14156,2663378,0,3295,0,4472,0,5625,0,1473,3576647,1527545,3694843,40685,12844,D1,P1,13490,26751,1407,2592840,756,75600,2163,2668440,5325.41,3549.17
21
+ 28/05/2023,4195,1302,2026053,5703,12334,2609966,0,2190,0,3737,0,5030,0,1401,3376177,1447089,2563297,42359,13543,D1,P1,13124,25607,1374,2558180,722,72200,2096,2630380,5282.85,3554.29
22
+ 29/05/2023,5265,1798,2328823,6483,14783,2537637,0,3954,0,5211,0,221,0,1575,3765997,1720747,2865333,39579,8116,D1,P1,15619,30688,1585,2979010,785,78500,2370,3057510,5961.63,4097.14
23
+ 30/05/2023,3879,1366,2294654,6008,15979,2489630,0,4465,0,6041,0,6,0,1192,3790830,1751416,2822819,37234,8830,D1,P1,17258,32693,1773,3270270,900,90000,2673,3360270,6752.47,4596.75
24
+ 31/05/2023,3933,1348,1645187,4081,14208,2337652,0,3797,0,4794,0,6,0,888,4151434,1953620,2714074,45856,6861,D1,P1,16458,31379,1688,3065730,924,92400,2612,3158130,6598.66,4373.22
25
+ 1/6/2023,4817,1530,1862175,4841,48192,3241822,0,3060,0,4802,0,12820,0,1137,4151797,1903421,2255850,51175,7095,D1,P1,17582,34622,1700,3231430,909,90900,2609,3322330,6342.48,4257.19
26
+ 2/6/2023,5733,1800,966546,2646,43573,4582872,0,1563,0,10678,0,46810,0,1309,4313201,2009602,2074692,47378,6120,D1,P1,25710,47869,2271,4131170,1130,113000,3401,4244170,6992.72,4747.36
27
+ 3/6/2023,4142,1290,2445721,11111,90587,4764628,0,2176,0,5144,0,27735,0,518,4514302,2083217,2095544,58527,5748,D1,P1,19247,37244,1905,3615570,961,96100,2866,3711670,5996.2,4065.63
28
+ 4/6/2023,5143,1613,2296690,6790,40929,4717779,0,1280,0,4237,0,5606,0,325,4179140,1889452,2152476,45239,6093,D1,P1,13474,29405,1475,2776480,755,75500,2230,2851980,5219.47,3571.73
29
+ 5/6/2023,5384,1832,3509278,8938,56272,19979584,0,1377,0,11493,0,25647,0,579,3683204,1641254,3616732,40356,6453,D1,P1,22558,54639,2114,4004520,1128,112800,3242,4117320,6672.4,4468.93
30
+ 6/6/2023,4802,1594,3216944,7861,20049,33102789,0,1485,0,9086,0,36532,0,545,3822453,1716540,3687300,53347,6334,D1,P1,26643,69935,2358,4505090,1222,122200,3580,4627290,6855.89,4686.82
31
+ 7/6/2023,5072,1648,2143372,5356,22553,21321547,0,1576,0,7213,0,21215,0,628,4178339,1811963,2354753,51632,6259,D1,P1,22242,56660,2125,3900920,1184,118400,3309,4019320,6611.5,4370.78
32
+ 8/6/2023,4444,1465,3190766,8024,53653,10254268,0,2046,0,10491,0,19549,0,769,3941272,1738344,2283350,59291,6775,D1,P1,23293,50105,2238,4145770,1270,127000,3508,4272770,6851.85,4515.66
33
+ 9/6/2023,4818,1605,3278715,9328,18347,4890758,0,1925,0,8360,0,32385,0,1732,3969227,1777864,2353376,52000,6026,D1,P1,25950,50611,2404,4657210,1315,131500,3719,4788710,6881.12,4639.8
34
+ 10/6/2023,3465,1207,2887842,8529,725,5489947,0,1230,0,5401,0,37954,0,2136,4458593,2061762,2535928,66567,5554,D1,P1,24413,47973,2370,4584570,1225,122500,3595,4707070,6334.68,4283.38
35
+ 11/6/2023,4727,1501,3149290,8114,738,5313957,0,1839,0,8198,0,32493,0,1533,4442610,2006438,2183963,47655,6008,D1,P1,23656,46275,2220,4441870,1183,118300,3403,4560170,6134.11,4098
36
+ 12/6/2023,6437,2208,4416005,12345,149561,5298884,0,1905,0,8542,0,101079,0,472,4645531,1995891,3301882,38760,4966,D1,P1,44382,76997,3520,6853780,1782,178200,5302,7031980,8549.02,5779.3
37
+ 13/06/2023,3556,1254,4626697,12984,258088,5952266,0,2095,0,10415,0,59770,0,1016,4508060,1912958,3440789,47281,4630,D1,P1,35764,67060,2737,5184020,1530,153000,4266,5335600,7908.1,5200.7
38
+ 14/06/2023,3178,1060,3389530,10298,685692,10454400,0,2258,0,24457,0,16016,0,1101,4573214,1920050,3160905,41549,5083,D1,P1,27677,56158,2257,4257990,1244,124400,3501,4382390,7187.71,4826.11
39
+ 15/06/2023,2981,999,3131350,10791,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4075106,1690702,3267810,50496,5037,D1,P1,23775,50354,2201,4212820,1215,121500,3416,4334320,7339.75,4890.1
40
+ 16/06/2023,2705,947,2923279,11124,1166424,11840950,0,1780,0,8938,0,24339,0,966,4533368,1939737,2881833,41872,4604,D1,P1,22957,49677,2225,4445430,1154,115400,3379,4560830,6663.77,4416.03
41
+ 17/06/2023,3697,1154,2955836,10440,807683,9748201,0,2139,0,5741,0,54129,0,766,4958344,2059487,3183051,52618,3675,D1,P1,26623,53187,2434,4755560,1286,128600,3723,4890110,6983.5,4694.41
42
+ 18/06/2023,3229,1080,3280006,12373,116340,8176712,0,1481,0,4741,0,16724,0,864,4270249,1735486,3251229,39780,3696,D1,P1,16690,36522,1715,3294460,936,93600,2651,3388060,5614.57,3749.6
43
+ 19/06/2023,3082,1003,6545797,24462,55763,4841897,0,2098,0,10520,0,26558,0,2211,4137846,1743715,2680413,43156,4347,D1,P1,25736,50759,2343,4515000,1244,124400,3587,4639400,7090.09,4789.96
44
+ 20/06/2023,2422,857,6734594,28910,52166,4718912,0,2205,0,10284,0,30610,0,1002,4218772,1771102,2058734,42288,4260,D1,P1,27941,52107,2478,4829920,1398,139800,3876,4969720,7584.9,4974.28
45
+ 21/06/2023,3366,1132,4784180,17247,52817,5971594,0,3387,0,9277,0,41697,0,645,4113884,1743016,2111350,44159,4193,D1,P1,28338,53853,2376,4353550,1357,135700,3733,4489250,7214.21,4702.88
46
+ 22/06/2023,2841,924,3300680,13360,29784,6803330,0,4064,0,7068,0,68638,0,481,3738171,1533407,1597072,35381,4173,D1,P1,34683,62182,2532,4863520,1434,143400,3966,5006920,7223.75,4679.68
47
+ 23/06/2023,2474,805,2284446,9012,80066,6833289,0,3274,0,7379,0,13501,0,721,4479743,1889155,1647740,39089,3640,D1,P1,16506,35549,1530,2980550,888,88800,2418,3069350,5295.75,3457.41
48
+ 24/06/2023,2462,814,1947190,7247,50309,6526903,0,2767,0,4703,0,8438,0,616,3758421,1565736,1648519,46332,3834,D1,P1,13804,31588,1381,2698000,788,78800,2169,2776800,4822.39,3136
49
+ 25/06/2023,2082,679,3560248,14850,50806,6368664,0,2767,0,4414,0,5346,0,628,4038846,1700182,2514456,43065,4201,D1,P1,13435,30121,1424,2782640,778,77800,2202,2860440,5082.66,3353.86
50
+ 26/06/2023,2399,839,5999950,28401,23209,10788275,0,3699,0,13383,0,13592,0,790,3427918,1403888,3598236,33883,4642,D1,P1,21114,49622,1959,3810990,1175,117500,3134,3928490,6965.39,4504.75
51
+ 27/06/2023,2307,804,5005495,18260,81344,14103220,0,7082,0,8898,0,40917,0,945,3819654,1523667,3556028,35326,4628,D1,P1,32019,65348,2877,5691820,1595,159500,4472,5851320,9589,6333.48
52
+ 28/06/2023,2215,759,3721084,11248,20153,10547995,0,8387,0,7120,0,39693,0,944,3671994,1568555,1397196,33212,2998,D1,P1,30267,63086,2863,5931970,1516,151600,4379,6083570,8919.81,5942.75
53
+ 29/06/2023,2013,706,3918049,10226,155296,8525871,0,10096,0,5693,0,24049,0,1512,3937747,1585655,3393043,30700,2519,D1,P1,22893,54097,2125,4215060,1132,113200,3257,4328260,7178.85,4806.94
54
+ 30/06/2023,1258,454,3088874,7943,902115,10945715,0,8904,0,9611,0,62404,0,1029,4945464,1946944,1835310,52445,2839,D1,P1,30707,67849,2616,5112840,1397,139700,4013,5252540,7664.09,5203.16
55
+ 1/7/2023,1641,539,3872657,12034,191537,12141356,0,4956,0,6049,0,31194,0,923,5328149,2224200,2123805,56724,2513,D1,P1,22229,54353,2266,4505840,1205,120500,3471,4626340,6983.83,4746.37
56
+ 2/7/2023,1336,485,5799582,17238,576858,12180985,0,4148,0,4670,0,4766,0,617,4527404,1997256,2038953,50510,21201,D1,P1,15205,43684,1672,3328290,886,88600,2559,3416990,5952.59,4038.91
57
+ 3/7/2023,2712,924,9986061,28191,442261,14059535,0,5347,0,7408,0,19028,0,1044,4179823,1854231,2234940,57543,14473,D1,P1,22798,57392,2425,4796940,1308,130800,3732,4925290,7701.44,5182.84
58
+ 4/7/2023,4137,1419,4717456,14519,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4449073,1959412,2350308,49085,9854,D1,P1,23585,60143,2220,4262060,1327,132700,3547,4394760,7689.38,5021.95
59
+ 5/7/2023,4166,1422,4779589,12676,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4464681,1969744,2390838,41411,12751,D1,P1,22847,61021,2348,4359400,1422,142200,3769,4497600,7976.49,5170.89
60
+ 6/7/2023,4182,1444,4939385,12222,2364811,15879491,0,6575,0,8461,0,18225,0,997,4490815,1942923,2239375,44808,16216,D1,P1,23716,60282,2602,4960450,1543,154300,4145,5114750,8225.73,5423.76
61
+ 7/7/2023,3497,1181,3121447,7534,1063284,17341347,0,6025,0,8113,0,25962,0,659,4891573,2128787,1976413,57373,12464,D1,P1,23336,58252,2335,4783910,1269,126900,3604,4910810,7182.26,4846.37
62
+ 8/7/2023,2760,856,3295227,9788,1119268,19207341,0,4102,0,6195,0,40506,0,832,5039604,2277255,2330435,44052,15163,D1,P1,22278,62471,2128,4352160,1191,119100,3319,4471260,6706.12,4485.38
63
+ 9/7/2023,2809,875,3913741,11815,749310,25182206,0,6420,0,5222,0,49626,0,718,4669470,2144473,3908306,49659,11716,D1,P1,24736,69003,2620,5573560,1325,132500,3945,5706060,7673.85,5278.59
64
+ 10/7/2023,4312,1489,5972974,18402,1511035,25950979,0,9842,0,10638,0,36204,0,935,4584106,2019220,4391654,52303,12983,D1,P1,28497,78251,2578,5157430,1419,141900,3997,5299330,8174.81,5453.8
65
+ 11/7/2023,4579,1550,4999618,16469,559119,23938153,0,11688,0,36570,0,25216,0,1289,4458364,1932300,4150666,47979,12292,D1,P1,28688,77223,2707,5384090,1483,148300,4190,5532390,8594.12,5787.78
66
+ 12/7/2023,4079,1418,4465722,13191,583520,25196511,0,4610,0,9813,0,20388,0,1210,4558876,2000168,4109583,54631,12366,D1,P1,25749,73523,2403,4926480,1410,141000,3813,5067480,8000.73,5259.61
67
+ 13/07/2023,3719,1260,4635033,12302,903614,25720336,0,7867,0,6792,0,22248,0,857,4596184,1957206,3729970,48474,11017,D1,P1,22447,69283,2134,4261960,1312,131200,3447,4393760,7385.89,4769.15
68
+ 14/07/2023,3632,1224,3441594,9800,1566300,28606996,0,6726,0,6172,0,14670,0,432,4683387,2007387,3912229,52588,10079,D1,P1,19225,67928,2002,3875450,1077,107700,3079,3983150,6615.15,4505.74
69
+ 15/07/2023,2909,941,6025085,21326,1836196,28705476,0,5705,0,4369,0,31202,0,595,5008167,2251661,3727627,58143,10214,D1,P1,19533,64001,2026,4112810,1066,106600,3093,4220310,6115.73,4122.89
70
+ 16/07/2023,2818,853,7339565,26586,4043959,26752554,0,7733,0,3961,0,27180,0,1082,4716541,2092258,2114014,59204,11281,D1,P1,18871,60797,1956,3715100,1126,112600,3084,3832400,6216.99,4066.5
71
+ 17/07/2023,4420,1486,9638491,32269,819444,29437537,0,11485,0,5220,0,66236,0,2418,4359325,1937825,1989872,55815,11896,D1,P1,35493,89662,2771,5539890,1521,152100,4292,5691990,8025.2,5388.69
72
+ 18/07/2023,4574,1551,9498457,31230,1206114,29164369,0,5012,0,7146,0,47074,0,2358,4882304,2163458,2157773,69573,12604,D1,P1,32238,84091,2687,5214920,1329,132900,4016,5347820,7833.63,5336.47
73
+ 19/07/2023,4632,1537,9742535,26935,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4613422,2080215,1981362,67495,12116,D1,P1,23193,69138,2342,4581910,1084,108400,3426,4690310,7118.68,4991.3
74
+ 20/07/2023,4891,1632,7630122,20720,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4484291,1922090,1663127,75312,12252,D1,P1,23193,63445,2209,4471970,995,99500,3255,4576570,6700.79,4599.1
75
+ 21/07/2023,3978,1378,7284968,21477,2456715,17869335,0,6360,0,10877,0,11431,0,769,4519305,1975730,1686467,68931,10065,D1,P1,21478,57996,2115,4257360,1006,100600,3121,4357960,6467.01,4497.43
76
+ 22/07/2023,3151,978,5638955,16181,2015345,12808440,0,7097,0,5145,0,13811,0,699,4689346,2086993,1861883,71898,9081,D1,P1,17602,50209,1897,3876970,830,83000,2727,3959970,5812.35,4126.62
77
+ 23/07/2023,2905,986,6133144,16089,881691,11267535,0,5593,0,4746,0,68021,0,514,4242878,1843843,1681215,61164,10797,D1,P1,25804,58279,2442,5168300,1161,116100,3603,5284400,6622.56,4639.27
78
+ 24/07/2023,4606,1651,8830736,21931,189913,35658281,0,8836,0,6040,0,64066,0,1626,3943001,1708849,1900126,59494,10236,D1,P1,31953,73505,2898,6111230,1424,142400,4321,6253530,8030.22,5492.47
79
+ 25/07/2023,4414,1597,7750251,15384,3348941,25011847,0,10262,0,9572,0,15072,0,916,3976490,1729916,1911109,68826,11468,D1,P1,26162,65005,2440,4822810,1154,115400,3594,4938210,7092.81,4965.39
80
+ 26/07/2023,4488,1530,8125332,16391,1040452,24380635,0,9947,0,16453,0,38777,0,1551,3837786,1680967,1856885,74924,13290,D1,P1,31894,69746,2797,5552460,1348,134800,4147,5687460,7359.12,5027.76
81
+ 27/07/2023,4105,1494,8054962,14724,220302,13070502,0,6758,0,8841,0,20622,0,1313,3636297,1544742,1772602,63935,11680,D1,P1,24634,57255,2498,5018670,1196,119600,3694,5138270,7106.66,4875.99
82
+ 28/07/2023,3743,1318,6955526,11566,3991586,5347413,0,10451,0,8496,0,20184,0,1563,3890784,1680538,1608577,73120,11390,D1,P1,22265,50660,2204,4515740,1054,105400,3258,4621140,6441.87,4432.07
83
+ 29/07/2023,3395,1192,5132501,9837,1349895,4441709,0,7115,0,5449,0,18983,0,1129,4295602,1813637,1824777,80511,11911,D1,P1,17626,42341,1930,3807270,860,86000,2790,3893270,5519.71,3922.54
84
+ 30/07/2023,2746,903,4903153,11018,710000,4431986,0,8491,0,4599,0,24834,0,1109,3924352,1733790,1740605,72221,11440,D1,P1,17619,43309,1942,3937090,834,83400,2776,4020490,5556.3,3945.89
85
+ 31/07/2023,4208,1476,6832832,19648,1721973,4079656,0,7754,0,7818,0,27918,0,2050,3760475,1501134,1957900,62124,11605,D1,P1,22728,51399,2256,4604950,1046,104600,3302,4709550,6481.79,4556.75
86
+ 1/8/2023,4203,1489,6398210,15890,2250090,5457683,0,7588,0,7948,0,61894,0,1248,3687038,1439092,1774701,61448,11492,D1,P1,31009,67515,2609,5471270,1309,130900,3918,5602170,6825.97,4671.87
87
+ 2/8/2023,4285,1515,5402871,14825,785167,6582085,0,6079,0,7236,0,79041,0,1345,3807266,1493340,2025308,54506,11515,D1,P1,34034,74123,2858,5856910,1360,136000,4218,5992910,7171.23,4989.3
88
+ 3/8/2023,4667,1744,4724924,8903,1111815,10407793,0,9077,0,7117,0,31714,0,1983,3797879,1479623,1718831,52587,11408,D1,P1,23978,62504,2404,4832400,1095,109500,3498,4941800,6670.71,4627.48
89
+ 4/8/2023,4201,1562,3732952,9116,4574481,10660977,0,8436,0,6970,0,25097,0,1055,3814852,1466211,1374674,57482,10785,D1,P1,21714,62922,2226,4561560,975,97500,3201,4659060,6133.71,4366.77
90
+ 5/8/2023,3080,1110,3310732,9884,3460283,11580456,0,5735,0,5049,0,5911,0,704,4048945,1601234,1442690,65158,9942,D1,P1,13792,52995,1578,3188640,720,72000,2298,3260640,4760.04,3375.44
91
+ 6/8/2023,2809,979,4153998,11663,5103054,8381689,0,4868,0,4184,0,28658,0,637,4040770,1250223,1844909,47698,10816,D1,P1,17706,56827,1841,3921270,842,84200,2683,4005470,5062.91,3520.39
92
+ 7/8/2023,3522,1186,3164171,10000,4137349,8709017,0,6112,0,6640,0,43866,0,1285,3928811,1288638,1861166,44623,11648,D1,P1,26772,71580,2456,4923260,1132,113200,3587,5034960,6580.87,4648.84
93
+ 8/8/2023,4111,1495,6020074,15008,2923076,5012245,0,6684,0,6961,0,12257,0,3038,3921429,1094791,2059462,48047,10379,D1,P1,22363,60212,2075,4138870,971,97100,3046,4235970,6286.57,4418.71
94
+ 9/8/2023,3609,1285,5616011,13195,2483117,3900778,0,8177,0,6447,0,12774,0,1309,3322165,452000,2262292,52219,11047,D1,P1,21099,53059,2067,4030270,1010,101000,3077,4131270,6309.32,4273.88
95
+ 10/8/2023,3872,1330,5270940,11342,1305507,3614496,0,6927,0,6602,0,21830,0,986,2868345,452896,1541791,46720,10556,D1,P1,22515,52055,2216,4848640,974,97400,3190,4946040,6281.59,4498.26
96
+ 11/8/2023,3673,1257,4485834,10445,3562053,5521177,0,5810,0,13751,0,5797,0,751,3242607,511016,1679989,47262,10344,D1,P1,17086,46491,1551,3242370,671,67100,2222,3309470,4608.96,3355.58
97
+ 12/8/2023,2744,960,3946512,10052,4015316,5813616,0,6205,0,10379,0,9890,0,532,3761072,595191,1931989,54787,9210,D1,P1,15949,46498,1376,3113130,639,63900,2016,3177130,4121.65,2907.82
98
+ 13/08/2023,2418,775,5051792,11809,1869057,6348414,0,4093,0,5187,0,21320,0,399,3279816,503805,2171335,55136,10546,D1,P1,14745,44224,1327,2888900,648,64800,1975,2953700,3905.29,2752.8
99
+ 14/08/2023,3551,1196,4839009,11805,1765326,3758610,0,6170,0,7226,0,19575,0,706,2974893,427940,1822890,49127,11042,D1,P1,20336,49993,1770,3798710,748,74800,2518,3873510,5195.83,3786.85
100
+ 15/08/2023,3430,1312,6520709,24857,1792924,1852314,0,6063,0,9302,0,34681,0,778,3080012,462344,1935145,57900,11083,D1,P1,24449,48710,1946,4332210,807,80700,2752,4412810,5367.05,3930.18
101
+ 16/08/2023,3253,1175,4844378,27290,3478033,1293346,0,5884,0,8280,0,29077,0,1055,3150093,468159,2094524,58937,11823,D1,P1,23892,46995,1911,3996580,780,78000,2691,4074580,5452.88,3979.2
102
+ 17/08/2023,3714,1417,4702754,23408,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3071572,444690,1961293,58681,10987,D1,P1,21265,42100,1700,3517380,704,70400,2404,3587780,5150.22,3718.85
103
+ 18/08/2023,1936,710,4370177,18919,3789636,1020973,0,9525,0,8958,0,32346,0,909,3252966,461174,2031390,61098,10354,D1,P1,20983,41383,1778,3654630,679,67900,2457,3722530,5019.58,3716.93
104
+ 19/08/2023,1998,723,3683868,14860,5187185,1336224,0,8305,0,6265,0,13396,0,1267,3460234,494225,2037289,68988,9709,D1,P1,14640,31119,1331,2887610,528,52800,1860,2943410,4059.2,3012.38
105
+ 20/08/2023,2458,839,5558511,16917,6444084,1333600,0,8083,0,5668,0,9425,0,593,3233047,427550,2093935,58698,11658,D1,P1,13616,29557,1227,2592690,476,47600,1703,2640290,3842.86,2850.38
106
+ 21/08/2023,2316,892,5802540,21997,1578062,1099659,0,9057,0,8434,0,11204,0,597,3110596,442523,1991499,71910,13059,D1,P1,19336,38812,1656,3445610,663,66300,2319,3510210,5100.16,3789.37
107
+ 22/08/2023,2208,845,5006504,13886,598218,939529,0,18631,0,11119,0,18304,0,666,3020862,419659,1960342,66769,12591,D1,P1,21348,42166,1844,3824050,762,76200,2582,3877380,5610.58,4088.17
108
+ 23/08/2023,2104,821,5240143,16309,1941212,2081327,0,17073,0,8077,0,6042,0,709,2634348,409468,1726842,53998,13783,D1,P1,18864,38949,1513,3153720,655,65500,2165,3219310,4984.78,3596.01
109
+ 24/08/2023,2011,685,5623870,14314,380971,2132605,0,13223,0,7340,0,11449,0,1774,2244344,385012,1409286,55699,13185,D1,P1,18821,38282,1665,3378840,678,67800,2358,3474730,5209.76,3795.85
110
+ 25/08/2023,1889,680,4674166,13506,1119189,1818097,0,33200,0,7250,0,16577,0,3622,2405697,395219,1564070,61103,13348,D1,P1,18364,37536,1863,3939560,638,63800,2501,4003360,5070.56,3850.47
111
+ 26/08/2023,1229,379,5475213,18030,476090,1048919,0,15316,0,4976,0,16625,0,3546,2662312,434769,1789446,61768,13346,D1,P1,16076,32992,1816,3388030,606,60600,2422,3448630,4877.02,3729.33
112
+ 27/08/2023,1333,486,5591938,13138,956722,732493,0,12952,0,4227,0,19562,0,2354,2470188,417919,1980888,53707,14151,D1,P1,14834,30563,1572,2979370,536,53600,2108,3032970,4232.88,3241.64
113
+ 28/08/2023,2031,760,7120359,17304,592505,571748,0,44816,0,8728,0,19999,0,3813,2357294,420574,1878047,50335,13442,D1,P1,20994,42982,1970,3877550,642,64200,2612,3941750,5610.5,4325.83
114
+ 29/08/2023,1560,550,6349650,18074,395464,276869,0,217642,0,8742,0,36555,0,2778,2437012,455532,1707585,52913,12648,D1,P1,25919,51217,2270,4323380,803,80300,3073,4403680,6223.41,4701.59
115
+ 30/08/2023,1788,623,6774580,17019,804715,227676,0,92490,0,7576,0,33376,0,1815,2461827,452647,1924554,57945,12244,D1,P1,24015,48307,2298,4414000,796,79600,3094,4493600,5983.31,4520.44
116
+ 31/08/2023,2251,790,6881955,16586,462096,216142,0,177608,0,7188,0,13212,0,1862,2630688,508779,1691540,44071,12093,D1,P1,17587,35874,1809,3406910,604,60400,2413,3467310,5218.62,4005.29
117
+ 1/9/2023,2763,930,5360505,17680,259775,323504,0,21865,0,7383,0,4899,0,1313,2723715,529388,1841032,48663,11275,D1,P1,13457,29785,1396,2542480,459,45900,1855,2588380,4243.41,3270.46
118
+ 2/9/2023,2597,870,4478842,15289,1226680,320820,0,26924,0,6477,0,4896,0,1454,2929332,613163,1945160,60288,10815,D1,P1,12337,27451,1347,2481120,508,50800,1855,2531920,4227.98,3109.35
119
+ 3/9/2023,2332,762,5174329,13994,449228,288375,0,20423,0,5755,0,10890,0,1494,2516381,558353,1697712,54329,11996,D1,P1,12609,27028,1428,2699310,481,48100,1909,2747410,4177.46,3164.79
120
+ 4/9/2023,3561,1229,5334952,17444,296660,306771,0,324815,0,7849,0,41134,0,2069,2485534,613680,1823512,52578,12787,D1,P1,22283,45146,2065,3908960,791,79100,2855,3987700,5743.35,4264.57
121
+ 5/9/2023,2261,816,6113505,20426,302910,227998,0,287642,0,7998,0,21025,0,1448,2453507,595873,1648165,49590,11749,D1,P1,19096,40015,1818,3314870,588,58800,2407,3377390,5367.87,4153.87
122
+ 6/9/2023,2868,1031,5558783,13407,1266416,255848,0,203777,0,8887,0,9020,0,933,2766708,736889,1987155,47189,10851,D1,P1,14311,31495,1502,2764430,499,49900,2001,2814330,4575.2,3510.97
123
+ 7/9/2023,2394,832,4907653,9041,191893,285511,0,202017,0,8317,0,6879,0,801,2616416,630668,1712157,47089,11632,D1,P1,13483,29283,1544,2846790,463,46300,2007,2893090,4770.64,3739.02
124
+ 8/9/2023,2689,910,4752031,8867,157343,302141,0,201772,0,8717,0,5684,0,1428,2705167,791338,1852090,43707,10493,D1,P1,13830,29726,1531,2806450,518,51800,2049,2858250,4807.58,3697.23
125
+ 9/9/2023,2204,752,3975657,10022,227113,245700,0,201776,0,7299,0,4098,0,758,2929279,827015,2001938,50033,10082,D1,P1,12284,26212,1414,2674080,433,43300,1847,2717380,4310.87,3354.94
126
+ 10/9/2023,2167,743,4243960,10399,270612,291468,0,201256,0,6099,0,8097,0,809,2352670,1241029,1966290,41767,10185,D1,P1,12594,26398,1498,2834900,435,43500,1933,2878400,4460.59,3531.69
127
+ 11/9/2023,3381,1227,4492340,10684,1192346,154867,0,202476,0,8393,0,6493,0,838,2573007,1455728,1830559,39596,12910,D1,P1,15510,32142,1544,2881650,449,44900,1992,2923700,4715.59,3736.66
128
+ 12/9/2023,2511,884,4936079,10015,199137,170680,0,50740,0,8506,0,26721,0,1085,2527461,1481401,1856155,40974,11883,D1,P1,22786,42733,2027,4286230,326,32600,2353,4318830,5172.4,4510.57
129
+ 13/09/2023,2143,778,5115564,10338,292239,238162,0,2408,0,7172,0,36811,0,836,2621020,1580825,1962940,39948,11634,D1,P1,22084,41155,1880,3809460,281,28100,2161,3837560,4765.04,4181.98
130
+ 14/09/2023,2307,798,4859067,12717,1181194,308251,0,948,0,7404,0,38152,0,1282,2677877,1397139,1251585,46129,10253,D1,P1,21377,40308,1959,3742130,550,55000,2509,3797130,5413.06,4301.68
131
+ 15/09/2023,2467,882,4260164,9702,399193,291844,0,756,0,6932,0,16060,0,2982,2751748,1416780,1269521,57909,10048,D1,P1,16118,32895,1659,3149040,526,52600,2185,3201640,4920.59,3802.04
132
+ 16/09/2023,2076,687,3350011,7707,620978,196303,0,663,0,6018,0,9889,0,1188,3083552,1564491,1439332,61159,9435,D1,P1,12830,26945,1488,2798420,446,44600,1934,2843020,4519.52,3564.8
133
+ 17/09/2023,2467,802,4503316,11119,581720,236009,0,637,0,4814,0,10024,0,2464,2935930,1503370,1649587,48796,10073,D1,P1,12357,25262,1396,2560250,455,45500,1851,2605750,4246.67,3287.31
134
+ 18/09/2023,2910,1024,5568066,14302,184276,143660,0,888,0,6922,0,10381,0,1767,2373681,1330212,1479501,51224,10488,D1,P1,16441,33582,1727,3152630,572,57200,2300,3209930,5491.87,4171.85
135
+ 19/09/2023,3252,1309,6105220,12193,208312,187769,0,1464,0,5210,0,8092,0,1504,2373344,1285881,1407015,40642,10547,D1,P1,17770,36578,1743,3229930,653,65300,2395,3291230,5666.71,4236.34
136
+ 20/09/2023,2796,1185,6055420,14003,291395,272928,0,1077,0,4246,0,10472,0,1830,2565110,1425196,1460886,48962,10318,D1,P1,16656,34188,1627,3048960,738,73800,2365,3121460,5577.7,3950.97
137
+ 21/09/2023,2208,878,5225528,8679,697480,160425,0,1033,0,6726,0,13928,0,1357,2686089,1447330,1236533,49940,10259,D1,P1,17253,34210,1912,3553480,811,81100,2723,3634580,6248.63,4440.07
138
+ 22/09/2023,1734,783,4373391,8141,2220006,88968,0,738,0,9534,0,8771,0,1690,2460283,1353647,1258771,45467,9910,D1,P1,14958,31389,1714,3084570,758,75800,2472,3160370,5984.05,4280.38
139
+ 23/09/2023,1190,492,4948823,10035,2432739,154849,0,702,0,8285,0,4369,0,806,2740252,1531672,1407980,51747,8665,D1,P1,12641,27336,1443,2653190,652,65200,2095,2718390,5094.46,3633.56
140
+ 24/09/2023,1124,496,6239124,10744,248085,231243,0,477,0,8032,0,8640,0,1449,2648532,1476875,1294436,36638,10410,D1,P1,12153,26113,1395,2618830,621,62100,2016,2680930,4558.91,3242.77
141
+ 25/09/2023,2358,1041,5325249,9804,251517,447312,0,591,0,11299,0,21103,0,1135,2371891,1333464,1222194,36894,9191,D1,P1,18608,38878,2041,3740860,897,89700,2938,3830560,6554.2,4744.62
142
+ 26/09/2023,2092,994,5361926,13223,90916,351820,0,910,0,10598,0,27697,0,2803,2612585,1502573,1256804,33211,8893,D1,P1,21214,41166,2128,3878240,935,93500,3063,3971740,6565.1,4696.86
143
+ 27/09/2023,1835,792,4600061,14060,728920,347014,0,1111,0,8811,0,104094,0,1780,2488689,1390273,1203937,33935,8769,D1,P1,37289,65137,2933,5530540,1595,159500,4525,5686340,8073.74,5545.54
144
+ 28/09/2023,1787,807,4114657,9434,84913,564139,0,279332,0,6975,0,51946,0,2516,2290090,1309586,1316086,32443,8606,D1,P1,25651,47307,2343,4257450,1199,119900,3542,4377350,7151.36,4963.98
145
+ 29/09/2023,1513,641,4477584,8505,211297,372199,0,443,0,4039,0,4466,0,1774,2429135,1379398,1425850,31700,7184,D1,P1,12276,26946,1488,2459350,613,61300,2101,2520650,5148.56,3726.34
146
+ 30/09/2023,1127,478,4089760,9316,222854,364180,0,517,0,3251,0,13297,0,1425,1049942,435407,548780,10869,4505,D1,P1,12905,27091,1533,2701900,640,64000,2173,2765900,5022.4,3685.32
147
+ 1/10/2023,1021,436,748856,2639,301970,224135,0,846,0,2731,0,7574,0,962,935755,413098,1084400,13147,5335,D1,P1,9103,18479,1165,2022810,467,46700,1632,2069510,3823.3,2818.63
148
+ 2/10/2023,1673,764,1692932,4211,387802,237932,0,1564,0,12820,0,9400,0,1463,877002,383352,1016934,14302,5965,D1,P1,12307,24110,1290,2265000,565,56500,1855,2321500,4314.73,3091.4
149
+ 3/10/2023,1516,725,1757367,3947,568156,171003,0,1739,0,21454,0,5276,0,1640,833524,365270,973716,14227,5936,D1,P1,12568,24900,1344,2390760,645,64500,1989,2455260,4686.71,3259.46
150
+ 4/10/2023,1786,763,1733340,3119,567654,129402,0,1726,0,15833,0,13543,0,2940,836392,368220,1029847,13931,5864,D1,P1,13780,26581,1383,2427230,695,69500,2078,2496730,4764.92,3278.39
151
+ 5/10/2023,1986,861,1671129,3736,504268,159069,0,1747,0,24285,0,8234,0,3163,830805,380396,476125,13399,5529,D1,P1,12797,24819,1428,2572910,640,64050,2067,2626960,4940.4,3504.67
152
+ 6/10/2023,1774,753,1348401,2784,702326,205479,0,1686,0,15228,0,12269,0,2107,817142,382879,504402,11840,5476,D1,P1,11345,22554,1268,2317850,601,60300,1869,2378150,4247.46,3014.11
153
+ 7/10/2023,1150,416,1175733,2242,359848,180366,0,1446,0,19417,0,27951,0,2050,921412,418533,520370,11215,5083,D1,P1,14047,25738,1516,3012040,684,68550,2200,3080590,4256.92,3052.07
154
+ 8/10/2023,999,337,1296701,2609,662748,293989,0,1415,0,14589,0,18476,0,1786,768086,352949,357821,12788,5550,D1,P1,11419,21977,1320,2426760,572,57400,1892,2484160,4025.59,2933.34
155
+ 9/10/2023,772,289,1942734,4167,3096792,191352,0,1855,0,24331,0,21658,0,1757,653538,261410,590317,14449,6333,D1,P1,14624,27809,1367,2649310,715,73600,2082,2722910,4326.63,2956.14
156
+ 10/10/2023,737,241,1911227,4238,565419,164827,0,2101,0,11526,0,9057,0,2720,734200,300476,568450,13952,6145,D1,P1,12640,24537,1376,2459930,653,68350,2029,2528280,4537.77,3219.59
157
+ 11/10/2023,681,256,2171216,4714,503802,216630,0,1921,0,7255,0,7549,0,2025,958835,399349,595481,12432,5599,D1,P1,11486,22322,1319,2395980,638,66400,1958,2463820,4317.3,3006.02
158
+ 12/10/2023,673,240,1820266,4067,233553,161215,0,8042,0,4686,0,5288,0,1408,861845,336598,557239,13130,5889,D1,P1,9536,18332,1167,1988790,536,56350,1702,2044540,3786.09,2688.23
159
+ 13/10/2023,595,233,1529402,3094,68852,156834,0,7184,0,4986,0,14364,0,1924,801772,317596,563967,12222,5539,D1,P1,12220,23105,1373,2510340,641,66600,2014,2576940,4218.4,2949.55
160
+ 14/10/2023,748,266,1013578,2156,48430,185877,0,3043,0,4287,0,14809,0,2117,929822,362662,603684,11533,5191,D1,P1,11280,21172,1275,2379750,592,62050,1867,2441800,3859.27,2715.54
161
+ 15/10/2023,602,201,1596953,4098,55580,222305,0,12269,0,4366,0,15778,0,1639,891052,327915,425822,13301,6358,D1,P1,10476,19507,1178,2129330,587,60800,1765,2190130,3766.36,2609.81
162
+ 16/10/2023,964,369,2144206,5169,31683,118393,0,6488,0,5537,0,65656,0,1254,842123,317951,810650,16455,7813,D1,P1,23493,39642,2233,4391770,1136,117850,3369,4509620,5998.13,4174.09
163
+ 17/10/2023,1105,415,2112245,5363,69479,70676,0,4964,0,4816,0,18719,0,2353,816941,328053,766996,14912,7402,D1,P1,15733,28542,1531,2735230,779,81300,2310,2816530,5078.87,3496.45
164
+ 18/10/2023,913,348,1892230,4633,451927,111742,0,4068,0,4855,0,32612,0,2028,957593,377866,689470,15228,7272,D1,P1,18694,32354,1918,3636660,883,91900,2801,3728560,5610.31,3986.54
165
+ 19/10/2023,914,302,1550243,3817,100009,183549,0,4309,0,4468,0,68322,0,2169,846076,336810,775970,14394,6925,D1,P1,26120,43767,2170,4171580,1158,120800,3328,4292380,5891.41,4024.57
166
+ 20/10/2023,663,208,1100622,2740,174916,181797,0,3695,0,4056,0,58835,0,1887,910115,366406,653096,15447,6572,D1,P1,22398,38504,2218,4385190,1035,108650,3253,4493840,5680.14,4012.57
167
+ 21/10/2023,559,184,1405730,3216,207981,276329,0,2723,0,3213,0,44899,0,1893,1184901,485051,850250,14780,6181,D1,P1,17236,31207,1638,3121900,793,82100,2431,3204000,4493.8,3159.39
168
+ 22/10/2023,545,198,1467468,3228,520836,253840,0,2213,0,2850,0,27411,0,1911,1154732,423852,1027954,10344,4893,D1,P1,13607,25217,1482,2893810,725,75700,2207,2969510,4332.98,3030.72
169
+ 23/10/2023,625,231,2018062,5517,333114,436011,0,2839,0,3772,0,11121,0,1351,1208181,428535,1111507,11684,6220,D1,P1,12048,23419,1256,2226550,585,61300,1840,2287750,4042.32,2864.75
170
+ 24/10/2023,574,226,1889784,5099,188275,228582,0,2709,0,2462,0,1109,0,1918,1083131,378488,1161439,11452,5728,D1,P1,10595,21221,1092,1909130,407,43350,1499,1952480,3725.66,2756.39
171
+ 25/10/2023,536,184,2276229,5661,77308,332105,0,2708,0,2679,0,525,0,2402,905535,310989,865636,11200,5884,D1,P1,10143,20535,887,1832160,331,37050,1218,1869210,3037.38,2236.69
172
+ 26/10/2023,609,200,1753696,4367,85971,236204,0,2136,0,2300,0,10,0,3842,968078,332008,771447,10098,5558,D1,P1,9900,19640,858,1671270,347,38950,1205,1710220,2995.78,2165.99
173
+ 27/10/2023,563,209,1636932,3338,246909,285904,0,1992,0,2323,0,5,0,2851,1063329,352124,929257,9507,5001,D1,P1,8240,17233,780,1422510,309,35500,1089,1458010,2635.69,1927
174
+ 28/10/2023,450,155,1588245,4276,235960,324079,0,2716,0,1753,0,1,0,2585,1191854,384343,1028724,8578,4958,D1,P1,7529,15744,725,1476840,300,33850,1025,1510690,2588.52,1884.51
175
+ 29/10/2023,309,117,1731474,5065,70210,331208,0,2241,0,1708,0,5,0,3120,1137463,385520,764681,10186,5650,D1,P1,7535,14889,747,1514990,287,32300,1034,1547290,2594.6,1909.86
176
+ 31/10/2023,486,182,2220653,5950,41641,213812,0,149,0,2404,0,15,0,1380,913362,318222,1020094,10416,3703,D1,P1,8678,18059,784,1613510,309,34550,1093,1648060,2844.9,2076.88
177
+ 1/11/2023,296,123,1834772,4275,201158,313487,0,889,0,2485,0,33093,0,2287,862276,316545,798469,11740,3972,D1,P1,16341,28782,1292,2880920,542,58750,1834,2939670,3468.46,2536.62
178
+ 2/11/2023,346,111,1697213,2987,1586296,64435,0,957,0,2130,0,16368,0,3586,840477,298617,830972,10008,3641,D1,P1,12216,22498,1071,2342490,402,43400,1473,2385890,3237.48,2396.17
179
+ 3/11/2023,224,89,1759831,2940,93667,74522,0,962,0,2484,0,14150,0,953,952592,350909,800378,11090,3818,D1,P1,10460,20113,902,1897210,372,40600,1274,1937810,2883.8,2066.5
180
+ 4/11/2023,214,76,1677064,2752,65182,61325,0,1796,0,3084,0,10438,0,1148,957265,344580,821570,11309,4380,D1,P1,8630,17741,757,1590600,290,31650,1047,1622250,2519.34,1826.6
181
+ 9/5/2023,6111,1916,1365036,5044,104781,31371909,0,3341,0,11190,0,61956,0,457,2371841,1021599,2302543,34816,19205,D2,P2,35411,86251,2786,4926900,1395,139500,4181,5066400,6110.89,4301.97
182
+ 10/5/2023,6233,1888,1234034,3899,140810,32973036,0,3214,0,9988,0,52049,0,705,2100238,943808,2336369,19716,17415,D2,P2,37986,96199,3087,5328400,1515,151500,4603,5480000,7186.64,5128.37
183
+ 11/5/2023,5568,1816,1016155,2788,102248,50729517,0,3203,0,10869,0,8042,0,381,2461265,1127717,1110415,21547,11051,D2,P2,24496,77036,2337,4001750,1327,132700,3663,4133100,5892.4,4091.77
184
+ 12/5/2023,5109,1769,1228032,3101,100246,63142114,0,2492,0,7096,0,10596,0,299,2313368,1107256,1191901,31966,11081,D2,P2,21030,75112,2052,3462310,1116,111600,3168,3573910,5091.46,3601.62
185
+ 13/05/2023,3712,1231,1344557,3399,100714,59509032,0,3986,0,4282,0,9753,0,366,3067797,1388882,1403486,38518,10762,D2,P2,16294,64652,1611,2693420,827,82700,2438,2776120,3925.27,2780.04
186
+ 14/05/2023,3719,1241,1520157,3491,120162,49538293,0,1891,0,3002,0,7363,0,278,3140882,1429620,2518831,44744,12151,D2,P2,13378,55706,1428,2535460,765,76500,2193,2611960,3658.41,2543.11
187
+ 15/05/2023,7735,2663,2102264,5175,106903,46609819,0,2518,0,4548,0,16201,0,880,2916228,1288902,2456845,36269,15290,D2,P2,21857,67301,2149,3844360,1075,107500,3223,3951760,5540.69,3945.07
188
+ 16/05/2023,9409,3206,2134290,5636,88201,9662393,0,2247,0,6690,0,15031,0,1588,3161940,1370882,2403330,37393,14187,D2,P2,26562,53380,2486,4026650,1251,125100,3736,4150900,6839.28,4817.99
189
+ 17/05/2023,8409,2785,1473128,4336,56382,2232239,0,2557,0,6401,0,8946,0,322,3199527,1379566,2608845,39190,12591,D2,P2,21930,41033,2100,3675940,1126,112600,3226,3788540,6156.6,4185.47
190
+ 18/05/2023,8364,2873,1733275,5009,38145,7321146,0,2912,0,7286,0,14366,0,660,2623727,1115471,1723470,36020,12100,D2,P2,21813,40251,1987,3528210,1240,124000,3227,3652210,6388.27,4150.71
191
+ 19/05/2023,6432,2050,1784426,5063,23340,8715910,0,3934,0,6035,0,20378,0,362,2995998,1287313,1959870,36885,12848,D2,P2,19874,38360,1888,3663690,1140,114000,3027,3777590,5981.25,3891.85
192
+ 20/05/2023,5428,1724,1635604,4408,34693,8783612,0,3318,0,4714,0,21030,0,236,2996479,1326416,1903323,31048,12256,D2,P2,17568,33060,1691,3342720,931,93100,2623,3437270,5113.91,3453.26
193
+ 21/05/2023,5657,1807,1788487,4492,24812,5015214,0,2253,0,4227,0,11656,0,494,3167634,1309450,3651254,33361,13073,D2,P2,14766,28367,1461,2940020,800,80000,2261,3020020,4874.35,3300.96
194
+ 22/05/2023,5768,2036,2176947,5688,25298,3002995,0,2739,0,8313,0,25663,0,1147,3573865,1548365,3939226,33410,14092,D2,P2,21520,40205,1854,3533540,1097,109700,2951,3643240,6425.41,4211.67
195
+ 23/05/2023,5051,1720,2359219,6966,24773,3005057,0,4738,0,13827,0,47900,0,965,3248157,1376975,3631390,35016,13025,D2,P2,29860,51811,2527,5012370,1339,133900,3866,5146270,7978.08,5238.68
196
+ 24/05/2023,6078,1977,1612918,4924,24591,2833280,0,4816,0,12417,0,94489,0,1254,3572793,1550315,3532105,37491,12546,D2,P2,41297,68099,2993,5666720,1655,165500,4648,5832220,8715.48,5761.11
197
+ 25/05/2023,6547,2075,1468456,3624,19705,2771412,0,5070,0,7395,0,70016,0,762,3164337,1353382,3253308,34658,13154,D2,P2,33436,56714,2588,5066960,1509,150900,4097,5217860,7939.09,5062.98
198
+ 26/05/2023,3719,1189,1770048,4874,16879,2875657,0,2855,0,6964,0,29015,0,627,2989794,1248779,3345390,38267,12788,D2,P2,22185,40261,2101,4010930,1130,113000,3231,4123930,6785.57,4495.67
199
+ 27/05/2023,3620,1145,1900387,5061,14156,2663378,0,3295,0,4472,0,5625,0,1473,3576647,1527545,3694843,40685,12844,D2,P2,13490,26751,1407,2592840,756,75600,2163,2668440,5325.41,3549.17
200
+ 28/05/2023,4195,1302,2026053,5703,12334,2609966,0,2190,0,3737,0,5030,0,1401,3376177,1447089,2563297,42359,13543,D2,P2,13124,25607,1374,2558180,722,72200,2096,2630380,5282.85,3554.29
201
+ 29/05/2023,5265,1798,2328823,6483,14783,2537637,0,3954,0,5211,0,221,0,1575,3765997,1720747,2865333,39579,8116,D2,P2,15619,30688,1585,2979010,785,78500,2370,3057510,5961.63,4097.14
202
+ 30/05/2023,3879,1366,2294654,6008,15979,2489630,0,4465,0,6041,0,6,0,1192,3790830,1751416,2822819,37234,8830,D2,P2,17258,32693,1773,3270270,900,90000,2673,3360270,6752.47,4596.75
203
+ 31/05/2023,3933,1348,1645187,4081,14208,2337652,0,3797,0,4794,0,6,0,888,4151434,1953620,2714074,45856,6861,D2,P2,16458,31379,1688,3065730,924,92400,2612,3158130,6598.66,4373.22
204
+ 1/6/2023,4817,1530,1862175,4841,48192,3241822,0,3060,0,4802,0,12820,0,1137,4151797,1903421,2255850,51175,7095,D2,P2,17582,34622,1700,3231430,909,90900,2609,3322330,6342.48,4257.19
205
+ 2/6/2023,5733,1800,966546,2646,43573,4582872,0,1563,0,10678,0,46810,0,1309,4313201,2009602,2074692,47378,6120,D2,P2,25710,47869,2271,4131170,1130,113000,3401,4244170,6992.72,4747.36
206
+ 3/6/2023,4142,1290,2445721,11111,90587,4764628,0,2176,0,5144,0,27735,0,518,4514302,2083217,2095544,58527,5748,D2,P2,19247,37244,1905,3615570,961,96100,2866,3711670,5996.2,4065.63
207
+ 4/6/2023,5143,1613,2296690,6790,40929,4717779,0,1280,0,4237,0,5606,0,325,4179140,1889452,2152476,45239,6093,D2,P2,13474,29405,1475,2776480,755,75500,2230,2851980,5219.47,3571.73
208
+ 5/6/2023,5384,1832,3509278,8938,56272,19979584,0,1377,0,11493,0,25647,0,579,3683204,1641254,3616732,40356,6453,D2,P2,22558,54639,2114,4004520,1128,112800,3242,4117320,6672.4,4468.93
209
+ 6/6/2023,4802,1594,3216944,7861,20049,33102789,0,1485,0,9086,0,36532,0,545,3822453,1716540,3687300,53347,6334,D2,P2,26643,69935,2358,4505090,1222,122200,3580,4627290,6855.89,4686.82
210
+ 7/6/2023,5072,1648,2143372,5356,22553,21321547,0,1576,0,7213,0,21215,0,628,4178339,1811963,2354753,51632,6259,D2,P2,22242,56660,2125,3900920,1184,118400,3309,4019320,6611.5,4370.78
211
+ 8/6/2023,4444,1465,3190766,8024,53653,10254268,0,2046,0,10491,0,19549,0,769,3941272,1738344,2283350,59291,6775,D2,P2,23293,50105,2238,4145770,1270,127000,3508,4272770,6851.85,4515.66
212
+ 9/6/2023,4818,1605,3278715,9328,18347,4890758,0,1925,0,8360,0,32385,0,1732,3969227,1777864,2353376,52000,6026,D2,P2,25950,50611,2404,4657210,1315,131500,3719,4788710,6881.12,4639.8
213
+ 10/6/2023,3465,1207,2887842,8529,725,5489947,0,1230,0,5401,0,37954,0,2136,4458593,2061762,2535928,66567,5554,D2,P2,24413,47973,2370,4584570,1225,122500,3595,4707070,6334.68,4283.38
214
+ 11/6/2023,4727,1501,3149290,8114,738,5313957,0,1839,0,8198,0,32493,0,1533,4442610,2006438,2183963,47655,6008,D2,P2,23656,46275,2220,4441870,1183,118300,3403,4560170,6134.11,4098
215
+ 12/6/2023,6437,2208,4416005,12345,149561,5298884,0,1905,0,8542,0,101079,0,472,4645531,1995891,3301882,38760,4966,D2,P2,44382,76997,3520,6853780,1782,178200,5302,7031980,8549.02,5779.3
216
+ 13/06/2023,3556,1254,4626697,12984,258088,5952266,0,2095,0,10415,0,59770,0,1016,4508060,1912958,3440789,47281,4630,D2,P2,35764,67060,2737,5184020,1530,153000,4266,5335600,7908.1,5200.7
217
+ 14/06/2023,3178,1060,3389530,10298,685692,10454400,0,2258,0,24457,0,16016,0,1101,4573214,1920050,3160905,41549,5083,D2,P2,27677,56158,2257,4257990,1244,124400,3501,4382390,7187.71,4826.11
218
+ 15/06/2023,2981,999,3131350,10791,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4075106,1690702,3267810,50496,5037,D2,P2,23775,50354,2201,4212820,1215,121500,3416,4334320,7339.75,4890.1
219
+ 16/06/2023,2705,947,2923279,11124,1166424,11840950,0,1780,0,8938,0,24339,0,966,4533368,1939737,2881833,41872,4604,D2,P2,22957,49677,2225,4445430,1154,115400,3379,4560830,6663.77,4416.03
220
+ 17/06/2023,3697,1154,2955836,10440,807683,9748201,0,2139,0,5741,0,54129,0,766,4958344,2059487,3183051,52618,3675,D2,P2,26623,53187,2434,4755560,1286,128600,3723,4890110,6983.5,4694.41
221
+ 18/06/2023,3229,1080,3280006,12373,116340,8176712,0,1481,0,4741,0,16724,0,864,4270249,1735486,3251229,39780,3696,D2,P2,16690,36522,1715,3294460,936,93600,2651,3388060,5614.57,3749.6
222
+ 19/06/2023,3082,1003,6545797,24462,55763,4841897,0,2098,0,10520,0,26558,0,2211,4137846,1743715,2680413,43156,4347,D2,P2,25736,50759,2343,4515000,1244,124400,3587,4639400,7090.09,4789.96
223
+ 20/06/2023,2422,857,6734594,28910,52166,4718912,0,2205,0,10284,0,30610,0,1002,4218772,1771102,2058734,42288,4260,D2,P2,27941,52107,2478,4829920,1398,139800,3876,4969720,7584.9,4974.28
224
+ 21/06/2023,3366,1132,4784180,17247,52817,5971594,0,3387,0,9277,0,41697,0,645,4113884,1743016,2111350,44159,4193,D2,P2,28338,53853,2376,4353550,1357,135700,3733,4489250,7214.21,4702.88
225
+ 22/06/2023,2841,924,3300680,13360,29784,6803330,0,4064,0,7068,0,68638,0,481,3738171,1533407,1597072,35381,4173,D2,P2,34683,62182,2532,4863520,1434,143400,3966,5006920,7223.75,4679.68
226
+ 23/06/2023,2474,805,2284446,9012,80066,6833289,0,3274,0,7379,0,13501,0,721,4479743,1889155,1647740,39089,3640,D2,P2,16506,35549,1530,2980550,888,88800,2418,3069350,5295.75,3457.41
227
+ 24/06/2023,2462,814,1947190,7247,50309,6526903,0,2767,0,4703,0,8438,0,616,3758421,1565736,1648519,46332,3834,D2,P2,13804,31588,1381,2698000,788,78800,2169,2776800,4822.39,3136
228
+ 25/06/2023,2082,679,3560248,14850,50806,6368664,0,2767,0,4414,0,5346,0,628,4038846,1700182,2514456,43065,4201,D2,P2,13435,30121,1424,2782640,778,77800,2202,2860440,5082.66,3353.86
229
+ 26/06/2023,2399,839,5999950,28401,23209,10788275,0,3699,0,13383,0,13592,0,790,3427918,1403888,3598236,33883,4642,D2,P2,21114,49622,1959,3810990,1175,117500,3134,3928490,6965.39,4504.75
230
+ 27/06/2023,2307,804,5005495,18260,81344,14103220,0,7082,0,8898,0,40917,0,945,3819654,1523667,3556028,35326,4628,D2,P2,32019,65348,2877,5691820,1595,159500,4472,5851320,9589,6333.48
231
+ 28/06/2023,2215,759,3721084,11248,20153,10547995,0,8387,0,7120,0,39693,0,944,3671994,1568555,1397196,33212,2998,D2,P2,30267,63086,2863,5931970,1516,151600,4379,6083570,8919.81,5942.75
232
+ 29/06/2023,2013,706,3918049,10226,155296,8525871,0,10096,0,5693,0,24049,0,1512,3937747,1585655,3393043,30700,2519,D2,P2,22893,54097,2125,4215060,1132,113200,3257,4328260,7178.85,4806.94
233
+ 30/06/2023,1258,454,3088874,7943,902115,10945715,0,8904,0,9611,0,62404,0,1029,4945464,1946944,1835310,52445,2839,D2,P2,30707,67849,2616,5112840,1397,139700,4013,5252540,7664.09,5203.16
234
+ 1/7/2023,1641,539,3872657,12034,191537,12141356,0,4956,0,6049,0,31194,0,923,5328149,2224200,2123805,56724,2513,D2,P2,22229,54353,2266,4505840,1205,120500,3471,4626340,6983.83,4746.37
235
+ 2/7/2023,1336,485,5799582,17238,576858,12180985,0,4148,0,4670,0,4766,0,617,4527404,1997256,2038953,50510,21201,D2,P2,15205,43684,1672,3328290,886,88600,2559,3416990,5952.59,4038.91
236
+ 3/7/2023,2712,924,9986061,28191,442261,14059535,0,5347,0,7408,0,19028,0,1044,4179823,1854231,2234940,57543,14473,D2,P2,22798,57392,2425,4796940,1308,130800,3732,4925290,7701.44,5182.84
237
+ 4/7/2023,4137,1419,4717456,14519,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4449073,1959412,2350308,49085,9854,D2,P2,23585,60143,2220,4262060,1327,132700,3547,4394760,7689.38,5021.95
238
+ 5/7/2023,4166,1422,4779589,12676,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4464681,1969744,2390838,41411,12751,D2,P2,22847,61021,2348,4359400,1422,142200,3769,4497600,7976.49,5170.89
239
+ 6/7/2023,4182,1444,4939385,12222,2364811,15879491,0,6575,0,8461,0,18225,0,997,4490815,1942923,2239375,44808,16216,D2,P2,23716,60282,2602,4960450,1543,154300,4145,5114750,8225.73,5423.76
240
+ 7/7/2023,3497,1181,3121447,7534,1063284,17341347,0,6025,0,8113,0,25962,0,659,4891573,2128787,1976413,57373,12464,D2,P2,23336,58252,2335,4783910,1269,126900,3604,4910810,7182.26,4846.37
241
+ 8/7/2023,2760,856,3295227,9788,1119268,19207341,0,4102,0,6195,0,40506,0,832,5039604,2277255,2330435,44052,15163,D2,P2,22278,62471,2128,4352160,1191,119100,3319,4471260,6706.12,4485.38
242
+ 9/7/2023,2809,875,3913741,11815,749310,25182206,0,6420,0,5222,0,49626,0,718,4669470,2144473,3908306,49659,11716,D2,P2,24736,69003,2620,5573560,1325,132500,3945,5706060,7673.85,5278.59
243
+ 10/7/2023,4312,1489,5972974,18402,1511035,25950979,0,9842,0,10638,0,36204,0,935,4584106,2019220,4391654,52303,12983,D2,P2,28497,78251,2578,5157430,1419,141900,3997,5299330,8174.81,5453.8
244
+ 11/7/2023,4579,1550,4999618,16469,559119,23938153,0,11688,0,36570,0,25216,0,1289,4458364,1932300,4150666,47979,12292,D2,P2,28688,77223,2707,5384090,1483,148300,4190,5532390,8594.12,5787.78
245
+ 12/7/2023,4079,1418,4465722,13191,583520,25196511,0,4610,0,9813,0,20388,0,1210,4558876,2000168,4109583,54631,12366,D2,P2,25749,73523,2403,4926480,1410,141000,3813,5067480,8000.73,5259.61
246
+ 13/07/2023,3719,1260,4635033,12302,903614,25720336,0,7867,0,6792,0,22248,0,857,4596184,1957206,3729970,48474,11017,D2,P2,22447,69283,2134,4261960,1312,131200,3447,4393760,7385.89,4769.15
247
+ 14/07/2023,3632,1224,3441594,9800,1566300,28606996,0,6726,0,6172,0,14670,0,432,4683387,2007387,3912229,52588,10079,D2,P2,19225,67928,2002,3875450,1077,107700,3079,3983150,6615.15,4505.74
248
+ 15/07/2023,2909,941,6025085,21326,1836196,28705476,0,5705,0,4369,0,31202,0,595,5008167,2251661,3727627,58143,10214,D2,P2,19533,64001,2026,4112810,1066,106600,3093,4220310,6115.73,4122.89
249
+ 16/07/2023,2818,853,7339565,26586,4043959,26752554,0,7733,0,3961,0,27180,0,1082,4716541,2092258,2114014,59204,11281,D2,P2,18871,60797,1956,3715100,1126,112600,3084,3832400,6216.99,4066.5
250
+ 17/07/2023,4420,1486,9638491,32269,819444,29437537,0,11485,0,5220,0,66236,0,2418,4359325,1937825,1989872,55815,11896,D2,P2,35493,89662,2771,5539890,1521,152100,4292,5691990,8025.2,5388.69
251
+ 18/07/2023,4574,1551,9498457,31230,1206114,29164369,0,5012,0,7146,0,47074,0,2358,4882304,2163458,2157773,69573,12604,D2,P2,32238,84091,2687,5214920,1329,132900,4016,5347820,7833.63,5336.47
252
+ 19/07/2023,4632,1537,9742535,26935,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4613422,2080215,1981362,67495,12116,D2,P2,23193,69138,2342,4581910,1084,108400,3426,4690310,7118.68,4991.3
253
+ 20/07/2023,4891,1632,7630122,20720,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4484291,1922090,1663127,75312,12252,D2,P2,23193,63445,2209,4471970,995,99500,3255,4576570,6700.79,4599.1
254
+ 21/07/2023,3978,1378,7284968,21477,2456715,17869335,0,6360,0,10877,0,11431,0,769,4519305,1975730,1686467,68931,10065,D2,P2,21478,57996,2115,4257360,1006,100600,3121,4357960,6467.01,4497.43
255
+ 22/07/2023,3151,978,5638955,16181,2015345,12808440,0,7097,0,5145,0,13811,0,699,4689346,2086993,1861883,71898,9081,D2,P2,17602,50209,1897,3876970,830,83000,2727,3959970,5812.35,4126.62
256
+ 23/07/2023,2905,986,6133144,16089,881691,11267535,0,5593,0,4746,0,68021,0,514,4242878,1843843,1681215,61164,10797,D2,P2,25804,58279,2442,5168300,1161,116100,3603,5284400,6622.56,4639.27
257
+ 24/07/2023,4606,1651,8830736,21931,189913,35658281,0,8836,0,6040,0,64066,0,1626,3943001,1708849,1900126,59494,10236,D2,P2,31953,73505,2898,6111230,1424,142400,4321,6253530,8030.22,5492.47
258
+ 25/07/2023,4414,1597,7750251,15384,3348941,25011847,0,10262,0,9572,0,15072,0,916,3976490,1729916,1911109,68826,11468,D2,P2,26162,65005,2440,4822810,1154,115400,3594,4938210,7092.81,4965.39
259
+ 26/07/2023,4488,1530,8125332,16391,1040452,24380635,0,9947,0,16453,0,38777,0,1551,3837786,1680967,1856885,74924,13290,D2,P2,31894,69746,2797,5552460,1348,134800,4147,5687460,7359.12,5027.76
260
+ 27/07/2023,4105,1494,8054962,14724,220302,13070502,0,6758,0,8841,0,20622,0,1313,3636297,1544742,1772602,63935,11680,D2,P2,24634,57255,2498,5018670,1196,119600,3694,5138270,7106.66,4875.99
261
+ 28/07/2023,3743,1318,6955526,11566,3991586,5347413,0,10451,0,8496,0,20184,0,1563,3890784,1680538,1608577,73120,11390,D2,P2,22265,50660,2204,4515740,1054,105400,3258,4621140,6441.87,4432.07
262
+ 29/07/2023,3395,1192,5132501,9837,1349895,4441709,0,7115,0,5449,0,18983,0,1129,4295602,1813637,1824777,80511,11911,D2,P2,17626,42341,1930,3807270,860,86000,2790,3893270,5519.71,3922.54
263
+ 30/07/2023,2746,903,4903153,11018,710000,4431986,0,8491,0,4599,0,24834,0,1109,3924352,1733790,1740605,72221,11440,D2,P2,17619,43309,1942,3937090,834,83400,2776,4020490,5556.3,3945.89
264
+ 31/07/2023,4208,1476,6832832,19648,1721973,4079656,0,7754,0,7818,0,27918,0,2050,3760475,1501134,1957900,62124,11605,D2,P2,22728,51399,2256,4604950,1046,104600,3302,4709550,6481.79,4556.75
265
+ 1/8/2023,4203,1489,6398210,15890,2250090,5457683,0,7588,0,7948,0,61894,0,1248,3687038,1439092,1774701,61448,11492,D2,P2,31009,67515,2609,5471270,1309,130900,3918,5602170,6825.97,4671.87
266
+ 2/8/2023,4285,1515,5402871,14825,785167,6582085,0,6079,0,7236,0,79041,0,1345,3807266,1493340,2025308,54506,11515,D2,P2,34034,74123,2858,5856910,1360,136000,4218,5992910,7171.23,4989.3
267
+ 3/8/2023,4667,1744,4724924,8903,1111815,10407793,0,9077,0,7117,0,31714,0,1983,3797879,1479623,1718831,52587,11408,D2,P2,23978,62504,2404,4832400,1095,109500,3498,4941800,6670.71,4627.48
268
+ 4/8/2023,4201,1562,3732952,9116,4574481,10660977,0,8436,0,6970,0,25097,0,1055,3814852,1466211,1374674,57482,10785,D2,P2,21714,62922,2226,4561560,975,97500,3201,4659060,6133.71,4366.77
269
+ 5/8/2023,3080,1110,3310732,9884,3460283,11580456,0,5735,0,5049,0,5911,0,704,4048945,1601234,1442690,65158,9942,D2,P2,13792,52995,1578,3188640,720,72000,2298,3260640,4760.04,3375.44
270
+ 6/8/2023,2809,979,4153998,11663,5103054,8381689,0,4868,0,4184,0,28658,0,637,4040770,1250223,1844909,47698,10816,D2,P2,17706,56827,1841,3921270,842,84200,2683,4005470,5062.91,3520.39
271
+ 7/8/2023,3522,1186,3164171,10000,4137349,8709017,0,6112,0,6640,0,43866,0,1285,3928811,1288638,1861166,44623,11648,D2,P2,26772,71580,2456,4923260,1132,113200,3587,5034960,6580.87,4648.84
272
+ 8/8/2023,4111,1495,6020074,15008,2923076,5012245,0,6684,0,6961,0,12257,0,3038,3921429,1094791,2059462,48047,10379,D2,P2,22363,60212,2075,4138870,971,97100,3046,4235970,6286.57,4418.71
273
+ 9/8/2023,3609,1285,5616011,13195,2483117,3900778,0,8177,0,6447,0,12774,0,1309,3322165,452000,2262292,52219,11047,D2,P2,21099,53059,2067,4030270,1010,101000,3077,4131270,6309.32,4273.88
274
+ 10/8/2023,3872,1330,5270940,11342,1305507,3614496,0,6927,0,6602,0,21830,0,986,2868345,452896,1541791,46720,10556,D2,P2,22515,52055,2216,4848640,974,97400,3190,4946040,6281.59,4498.26
275
+ 11/8/2023,3673,1257,4485834,10445,3562053,5521177,0,5810,0,13751,0,5797,0,751,3242607,511016,1679989,47262,10344,D2,P2,17086,46491,1551,3242370,671,67100,2222,3309470,4608.96,3355.58
276
+ 12/8/2023,2744,960,3946512,10052,4015316,5813616,0,6205,0,10379,0,9890,0,532,3761072,595191,1931989,54787,9210,D2,P2,15949,46498,1376,3113130,639,63900,2016,3177130,4121.65,2907.82
277
+ 13/08/2023,2418,775,5051792,11809,1869057,6348414,0,4093,0,5187,0,21320,0,399,3279816,503805,2171335,55136,10546,D2,P2,14745,44224,1327,2888900,648,64800,1975,2953700,3905.29,2752.8
278
+ 14/08/2023,3551,1196,4839009,11805,1765326,3758610,0,6170,0,7226,0,19575,0,706,2974893,427940,1822890,49127,11042,D2,P2,20336,49993,1770,3798710,748,74800,2518,3873510,5195.83,3786.85
279
+ 15/08/2023,3430,1312,6520709,24857,1792924,1852314,0,6063,0,9302,0,34681,0,778,3080012,462344,1935145,57900,11083,D2,P2,24449,48710,1946,4332210,807,80700,2752,4412810,5367.05,3930.18
280
+ 16/08/2023,3253,1175,4844378,27290,3478033,1293346,0,5884,0,8280,0,29077,0,1055,3150093,468159,2094524,58937,11823,D2,P2,23892,46995,1911,3996580,780,78000,2691,4074580,5452.88,3979.2
281
+ 17/08/2023,3714,1417,4702754,23408,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3071572,444690,1961293,58681,10987,D2,P2,21265,42100,1700,3517380,704,70400,2404,3587780,5150.22,3718.85
282
+ 18/08/2023,1936,710,4370177,18919,3789636,1020973,0,9525,0,8958,0,32346,0,909,3252966,461174,2031390,61098,10354,D2,P2,20983,41383,1778,3654630,679,67900,2457,3722530,5019.58,3716.93
283
+ 19/08/2023,1998,723,3683868,14860,5187185,1336224,0,8305,0,6265,0,13396,0,1267,3460234,494225,2037289,68988,9709,D2,P2,14640,31119,1331,2887610,528,52800,1860,2943410,4059.2,3012.38
284
+ 20/08/2023,2458,839,5558511,16917,6444084,1333600,0,8083,0,5668,0,9425,0,593,3233047,427550,2093935,58698,11658,D2,P2,13616,29557,1227,2592690,476,47600,1703,2640290,3842.86,2850.38
285
+ 21/08/2023,2316,892,5802540,21997,1578062,1099659,0,9057,0,8434,0,11204,0,597,3110596,442523,1991499,71910,13059,D2,P2,19336,38812,1656,3445610,663,66300,2319,3510210,5100.16,3789.37
286
+ 22/08/2023,2208,845,5006504,13886,598218,939529,0,18631,0,11119,0,18304,0,666,3020862,419659,1960342,66769,12591,D2,P2,21348,42166,1844,3824050,762,76200,2582,3877380,5610.58,4088.17
287
+ 23/08/2023,2104,821,5240143,16309,1941212,2081327,0,17073,0,8077,0,6042,0,709,2634348,409468,1726842,53998,13783,D2,P2,18864,38949,1513,3153720,655,65500,2165,3219310,4984.78,3596.01
288
+ 24/08/2023,2011,685,5623870,14314,380971,2132605,0,13223,0,7340,0,11449,0,1774,2244344,385012,1409286,55699,13185,D2,P2,18821,38282,1665,3378840,678,67800,2358,3474730,5209.76,3795.85
289
+ 25/08/2023,1889,680,4674166,13506,1119189,1818097,0,33200,0,7250,0,16577,0,3622,2405697,395219,1564070,61103,13348,D2,P2,18364,37536,1863,3939560,638,63800,2501,4003360,5070.56,3850.47
290
+ 26/08/2023,1229,379,5475213,18030,476090,1048919,0,15316,0,4976,0,16625,0,3546,2662312,434769,1789446,61768,13346,D2,P2,16076,32992,1816,3388030,606,60600,2422,3448630,4877.02,3729.33
291
+ 27/08/2023,1333,486,5591938,13138,956722,732493,0,12952,0,4227,0,19562,0,2354,2470188,417919,1980888,53707,14151,D2,P2,14834,30563,1572,2979370,536,53600,2108,3032970,4232.88,3241.64
292
+ 28/08/2023,2031,760,7120359,17304,592505,571748,0,44816,0,8728,0,19999,0,3813,2357294,420574,1878047,50335,13442,D2,P2,20994,42982,1970,3877550,642,64200,2612,3941750,5610.5,4325.83
293
+ 29/08/2023,1560,550,6349650,18074,395464,276869,0,217642,0,8742,0,36555,0,2778,2437012,455532,1707585,52913,12648,D2,P2,25919,51217,2270,4323380,803,80300,3073,4403680,6223.41,4701.59
294
+ 30/08/2023,1788,623,6774580,17019,804715,227676,0,92490,0,7576,0,33376,0,1815,2461827,452647,1924554,57945,12244,D2,P2,24015,48307,2298,4414000,796,79600,3094,4493600,5983.31,4520.44
295
+ 31/08/2023,2251,790,6881955,16586,462096,216142,0,177608,0,7188,0,13212,0,1862,2630688,508779,1691540,44071,12093,D2,P2,17587,35874,1809,3406910,604,60400,2413,3467310,5218.62,4005.29
296
+ 1/9/2023,2763,930,5360505,17680,259775,323504,0,21865,0,7383,0,4899,0,1313,2723715,529388,1841032,48663,11275,D2,P2,13457,29785,1396,2542480,459,45900,1855,2588380,4243.41,3270.46
297
+ 2/9/2023,2597,870,4478842,15289,1226680,320820,0,26924,0,6477,0,4896,0,1454,2929332,613163,1945160,60288,10815,D2,P2,12337,27451,1347,2481120,508,50800,1855,2531920,4227.98,3109.35
298
+ 3/9/2023,2332,762,5174329,13994,449228,288375,0,20423,0,5755,0,10890,0,1494,2516381,558353,1697712,54329,11996,D2,P2,12609,27028,1428,2699310,481,48100,1909,2747410,4177.46,3164.79
299
+ 4/9/2023,3561,1229,5334952,17444,296660,306771,0,324815,0,7849,0,41134,0,2069,2485534,613680,1823512,52578,12787,D2,P2,22283,45146,2065,3908960,791,79100,2855,3987700,5743.35,4264.57
300
+ 5/9/2023,2261,816,6113505,20426,302910,227998,0,287642,0,7998,0,21025,0,1448,2453507,595873,1648165,49590,11749,D2,P2,19096,40015,1818,3314870,588,58800,2407,3377390,5367.87,4153.87
301
+ 6/9/2023,2868,1031,5558783,13407,1266416,255848,0,203777,0,8887,0,9020,0,933,2766708,736889,1987155,47189,10851,D2,P2,14311,31495,1502,2764430,499,49900,2001,2814330,4575.2,3510.97
302
+ 7/9/2023,2394,832,4907653,9041,191893,285511,0,202017,0,8317,0,6879,0,801,2616416,630668,1712157,47089,11632,D2,P2,13483,29283,1544,2846790,463,46300,2007,2893090,4770.64,3739.02
303
+ 8/9/2023,2689,910,4752031,8867,157343,302141,0,201772,0,8717,0,5684,0,1428,2705167,791338,1852090,43707,10493,D2,P2,13830,29726,1531,2806450,518,51800,2049,2858250,4807.58,3697.23
304
+ 9/9/2023,2204,752,3975657,10022,227113,245700,0,201776,0,7299,0,4098,0,758,2929279,827015,2001938,50033,10082,D2,P2,12284,26212,1414,2674080,433,43300,1847,2717380,4310.87,3354.94
305
+ 10/9/2023,2167,743,4243960,10399,270612,291468,0,201256,0,6099,0,8097,0,809,2352670,1241029,1966290,41767,10185,D2,P2,12594,26398,1498,2834900,435,43500,1933,2878400,4460.59,3531.69
306
+ 11/9/2023,3381,1227,4492340,10684,1192346,154867,0,202476,0,8393,0,6493,0,838,2573007,1455728,1830559,39596,12910,D2,P2,15510,32142,1544,2881650,449,44900,1992,2923700,4715.59,3736.66
307
+ 12/9/2023,2511,884,4936079,10015,199137,170680,0,50740,0,8506,0,26721,0,1085,2527461,1481401,1856155,40974,11883,D2,P2,22786,42733,2027,4286230,326,32600,2353,4318830,5172.4,4510.57
308
+ 13/09/2023,2143,778,5115564,10338,292239,238162,0,2408,0,7172,0,36811,0,836,2621020,1580825,1962940,39948,11634,D2,P2,22084,41155,1880,3809460,281,28100,2161,3837560,4765.04,4181.98
309
+ 14/09/2023,2307,798,4859067,12717,1181194,308251,0,948,0,7404,0,38152,0,1282,2677877,1397139,1251585,46129,10253,D2,P2,21377,40308,1959,3742130,550,55000,2509,3797130,5413.06,4301.68
310
+ 15/09/2023,2467,882,4260164,9702,399193,291844,0,756,0,6932,0,16060,0,2982,2751748,1416780,1269521,57909,10048,D2,P2,16118,32895,1659,3149040,526,52600,2185,3201640,4920.59,3802.04
311
+ 16/09/2023,2076,687,3350011,7707,620978,196303,0,663,0,6018,0,9889,0,1188,3083552,1564491,1439332,61159,9435,D2,P2,12830,26945,1488,2798420,446,44600,1934,2843020,4519.52,3564.8
312
+ 17/09/2023,2467,802,4503316,11119,581720,236009,0,637,0,4814,0,10024,0,2464,2935930,1503370,1649587,48796,10073,D2,P2,12357,25262,1396,2560250,455,45500,1851,2605750,4246.67,3287.31
313
+ 18/09/2023,2910,1024,5568066,14302,184276,143660,0,888,0,6922,0,10381,0,1767,2373681,1330212,1479501,51224,10488,D2,P2,16441,33582,1727,3152630,572,57200,2300,3209930,5491.87,4171.85
314
+ 19/09/2023,3252,1309,6105220,12193,208312,187769,0,1464,0,5210,0,8092,0,1504,2373344,1285881,1407015,40642,10547,D2,P2,17770,36578,1743,3229930,653,65300,2395,3291230,5666.71,4236.34
315
+ 20/09/2023,2796,1185,6055420,14003,291395,272928,0,1077,0,4246,0,10472,0,1830,2565110,1425196,1460886,48962,10318,D2,P2,16656,34188,1627,3048960,738,73800,2365,3121460,5577.7,3950.97
316
+ 21/09/2023,2208,878,5225528,8679,697480,160425,0,1033,0,6726,0,13928,0,1357,2686089,1447330,1236533,49940,10259,D2,P2,17253,34210,1912,3553480,811,81100,2723,3634580,6248.63,4440.07
317
+ 22/09/2023,1734,783,4373391,8141,2220006,88968,0,738,0,9534,0,8771,0,1690,2460283,1353647,1258771,45467,9910,D2,P2,14958,31389,1714,3084570,758,75800,2472,3160370,5984.05,4280.38
318
+ 23/09/2023,1190,492,4948823,10035,2432739,154849,0,702,0,8285,0,4369,0,806,2740252,1531672,1407980,51747,8665,D2,P2,12641,27336,1443,2653190,652,65200,2095,2718390,5094.46,3633.56
319
+ 24/09/2023,1124,496,6239124,10744,248085,231243,0,477,0,8032,0,8640,0,1449,2648532,1476875,1294436,36638,10410,D2,P2,12153,26113,1395,2618830,621,62100,2016,2680930,4558.91,3242.77
320
+ 25/09/2023,2358,1041,5325249,9804,251517,447312,0,591,0,11299,0,21103,0,1135,2371891,1333464,1222194,36894,9191,D2,P2,18608,38878,2041,3740860,897,89700,2938,3830560,6554.2,4744.62
321
+ 26/09/2023,2092,994,5361926,13223,90916,351820,0,910,0,10598,0,27697,0,2803,2612585,1502573,1256804,33211,8893,D2,P2,21214,41166,2128,3878240,935,93500,3063,3971740,6565.1,4696.86
322
+ 27/09/2023,1835,792,4600061,14060,728920,347014,0,1111,0,8811,0,104094,0,1780,2488689,1390273,1203937,33935,8769,D2,P2,37289,65137,2933,5530540,1595,159500,4525,5686340,8073.74,5545.54
323
+ 28/09/2023,1787,807,4114657,9434,84913,564139,0,279332,0,6975,0,51946,0,2516,2290090,1309586,1316086,32443,8606,D2,P2,25651,47307,2343,4257450,1199,119900,3542,4377350,7151.36,4963.98
324
+ 29/09/2023,1513,641,4477584,8505,211297,372199,0,443,0,4039,0,4466,0,1774,2429135,1379398,1425850,31700,7184,D2,P2,12276,26946,1488,2459350,613,61300,2101,2520650,5148.56,3726.34
325
+ 30/09/2023,1127,478,4089760,9316,222854,364180,0,517,0,3251,0,13297,0,1425,1049942,435407,548780,10869,4505,D2,P2,12905,27091,1533,2701900,640,64000,2173,2765900,5022.4,3685.32
326
+ 1/10/2023,1021,436,748856,2639,301970,224135,0,846,0,2731,0,7574,0,962,935755,413098,1084400,13147,5335,D2,P2,9103,18479,1165,2022810,467,46700,1632,2069510,3823.3,2818.63
327
+ 2/10/2023,1673,764,1692932,4211,387802,237932,0,1564,0,12820,0,9400,0,1463,877002,383352,1016934,14302,5965,D2,P2,12307,24110,1290,2265000,565,56500,1855,2321500,4314.73,3091.4
328
+ 3/10/2023,1516,725,1757367,3947,568156,171003,0,1739,0,21454,0,5276,0,1640,833524,365270,973716,14227,5936,D2,P2,12568,24900,1344,2390760,645,64500,1989,2455260,4686.71,3259.46
329
+ 4/10/2023,1786,763,1733340,3119,567654,129402,0,1726,0,15833,0,13543,0,2940,836392,368220,1029847,13931,5864,D2,P2,13780,26581,1383,2427230,695,69500,2078,2496730,4764.92,3278.39
330
+ 5/10/2023,1986,861,1671129,3736,504268,159069,0,1747,0,24285,0,8234,0,3163,830805,380396,476125,13399,5529,D2,P2,12797,24819,1428,2572910,640,64050,2067,2626960,4940.4,3504.67
331
+ 6/10/2023,1774,753,1348401,2784,702326,205479,0,1686,0,15228,0,12269,0,2107,817142,382879,504402,11840,5476,D2,P2,11345,22554,1268,2317850,601,60300,1869,2378150,4247.46,3014.11
332
+ 7/10/2023,1150,416,1175733,2242,359848,180366,0,1446,0,19417,0,27951,0,2050,921412,418533,520370,11215,5083,D2,P2,14047,25738,1516,3012040,684,68550,2200,3080590,4256.92,3052.07
333
+ 8/10/2023,999,337,1296701,2609,662748,293989,0,1415,0,14589,0,18476,0,1786,768086,352949,357821,12788,5550,D2,P2,11419,21977,1320,2426760,572,57400,1892,2484160,4025.59,2933.34
334
+ 9/10/2023,772,289,1942734,4167,3096792,191352,0,1855,0,24331,0,21658,0,1757,653538,261410,590317,14449,6333,D2,P2,14624,27809,1367,2649310,715,73600,2082,2722910,4326.63,2956.14
335
+ 10/10/2023,737,241,1911227,4238,565419,164827,0,2101,0,11526,0,9057,0,2720,734200,300476,568450,13952,6145,D2,P2,12640,24537,1376,2459930,653,68350,2029,2528280,4537.77,3219.59
336
+ 11/10/2023,681,256,2171216,4714,503802,216630,0,1921,0,7255,0,7549,0,2025,958835,399349,595481,12432,5599,D2,P2,11486,22322,1319,2395980,638,66400,1958,2463820,4317.3,3006.02
337
+ 12/10/2023,673,240,1820266,4067,233553,161215,0,8042,0,4686,0,5288,0,1408,861845,336598,557239,13130,5889,D2,P2,9536,18332,1167,1988790,536,56350,1702,2044540,3786.09,2688.23
338
+ 13/10/2023,595,233,1529402,3094,68852,156834,0,7184,0,4986,0,14364,0,1924,801772,317596,563967,12222,5539,D2,P2,12220,23105,1373,2510340,641,66600,2014,2576940,4218.4,2949.55
339
+ 14/10/2023,748,266,1013578,2156,48430,185877,0,3043,0,4287,0,14809,0,2117,929822,362662,603684,11533,5191,D2,P2,11280,21172,1275,2379750,592,62050,1867,2441800,3859.27,2715.54
340
+ 15/10/2023,602,201,1596953,4098,55580,222305,0,12269,0,4366,0,15778,0,1639,891052,327915,425822,13301,6358,D2,P2,10476,19507,1178,2129330,587,60800,1765,2190130,3766.36,2609.81
341
+ 16/10/2023,964,369,2144206,5169,31683,118393,0,6488,0,5537,0,65656,0,1254,842123,317951,810650,16455,7813,D2,P2,23493,39642,2233,4391770,1136,117850,3369,4509620,5998.13,4174.09
342
+ 17/10/2023,1105,415,2112245,5363,69479,70676,0,4964,0,4816,0,18719,0,2353,816941,328053,766996,14912,7402,D2,P2,15733,28542,1531,2735230,779,81300,2310,2816530,5078.87,3496.45
343
+ 18/10/2023,913,348,1892230,4633,451927,111742,0,4068,0,4855,0,32612,0,2028,957593,377866,689470,15228,7272,D2,P2,18694,32354,1918,3636660,883,91900,2801,3728560,5610.31,3986.54
344
+ 19/10/2023,914,302,1550243,3817,100009,183549,0,4309,0,4468,0,68322,0,2169,846076,336810,775970,14394,6925,D2,P2,26120,43767,2170,4171580,1158,120800,3328,4292380,5891.41,4024.57
345
+ 20/10/2023,663,208,1100622,2740,174916,181797,0,3695,0,4056,0,58835,0,1887,910115,366406,653096,15447,6572,D2,P2,22398,38504,2218,4385190,1035,108650,3253,4493840,5680.14,4012.57
346
+ 21/10/2023,559,184,1405730,3216,207981,276329,0,2723,0,3213,0,44899,0,1893,1184901,485051,850250,14780,6181,D2,P2,17236,31207,1638,3121900,793,82100,2431,3204000,4493.8,3159.39
347
+ 22/10/2023,545,198,1467468,3228,520836,253840,0,2213,0,2850,0,27411,0,1911,1154732,423852,1027954,10344,4893,D2,P2,13607,25217,1482,2893810,725,75700,2207,2969510,4332.98,3030.72
348
+ 23/10/2023,625,231,2018062,5517,333114,436011,0,2839,0,3772,0,11121,0,1351,1208181,428535,1111507,11684,6220,D2,P2,12048,23419,1256,2226550,585,61300,1840,2287750,4042.32,2864.75
349
+ 24/10/2023,574,226,1889784,5099,188275,228582,0,2709,0,2462,0,1109,0,1918,1083131,378488,1161439,11452,5728,D2,P2,10595,21221,1092,1909130,407,43350,1499,1952480,3725.66,2756.39
350
+ 25/10/2023,536,184,2276229,5661,77308,332105,0,2708,0,2679,0,525,0,2402,905535,310989,865636,11200,5884,D2,P2,10143,20535,887,1832160,331,37050,1218,1869210,3037.38,2236.69
351
+ 26/10/2023,609,200,1753696,4367,85971,236204,0,2136,0,2300,0,10,0,3842,968078,332008,771447,10098,5558,D2,P2,9900,19640,858,1671270,347,38950,1205,1710220,2995.78,2165.99
352
+ 27/10/2023,563,209,1636932,3338,246909,285904,0,1992,0,2323,0,5,0,2851,1063329,352124,929257,9507,5001,D2,P2,8240,17233,780,1422510,309,35500,1089,1458010,2635.69,1927
353
+ 28/10/2023,450,155,1588245,4276,235960,324079,0,2716,0,1753,0,1,0,2585,1191854,384343,1028724,8578,4958,D2,P2,7529,15744,725,1476840,300,33850,1025,1510690,2588.52,1884.51
354
+ 29/10/2023,309,117,1731474,5065,70210,331208,0,2241,0,1708,0,5,0,3120,1137463,385520,764681,10186,5650,D2,P2,7535,14889,747,1514990,287,32300,1034,1547290,2594.6,1909.86
355
+ 31/10/2023,486,182,2220653,5950,41641,213812,0,149,0,2404,0,15,0,1380,913362,318222,1020094,10416,3703,D2,P2,8678,18059,784,1613510,309,34550,1093,1648060,2844.9,2076.88
356
+ 1/11/2023,296,123,1834772,4275,201158,313487,0,889,0,2485,0,33093,0,2287,862276,316545,798469,11740,3972,D2,P2,16341,28782,1292,2880920,542,58750,1834,2939670,3468.46,2536.62
357
+ 2/11/2023,346,111,1697213,2987,1586296,64435,0,957,0,2130,0,16368,0,3586,840477,298617,830972,10008,3641,D2,P2,12216,22498,1071,2342490,402,43400,1473,2385890,3237.48,2396.17
358
+ 3/11/2023,224,89,1759831,2940,93667,74522,0,962,0,2484,0,14150,0,953,952592,350909,800378,11090,3818,D2,P2,10460,20113,902,1897210,372,40600,1274,1937810,2883.8,2066.5
359
+ 4/11/2023,214,76,1677064,2752,65182,61325,0,1796,0,3084,0,10438,0,1148,957265,344580,821570,11309,4380,D2,P2,8630,17741,757,1590600,290,31650,1047,1622250,2519.34,1826.6
360
+ 9/5/2023,6111,1916,1365036,5044,104781,31371909,0,3341,0,11190,0,61956,0,457,2371841,1021599,2302543,34816,19205,D3,P3,35411,86251,2786,4926900,1395,139500,4181,5066400,6110.89,4301.97
361
+ 10/5/2023,6233,1888,1234034,3899,140810,32973036,0,3214,0,9988,0,52049,0,705,2100238,943808,2336369,19716,17415,D3,P3,37986,96199,3087,5328400,1515,151500,4603,5480000,7186.64,5128.37
362
+ 11/5/2023,5568,1816,1016155,2788,102248,50729517,0,3203,0,10869,0,8042,0,381,2461265,1127717,1110415,21547,11051,D3,P3,24496,77036,2337,4001750,1327,132700,3663,4133100,5892.4,4091.77
363
+ 12/5/2023,5109,1769,1228032,3101,100246,63142114,0,2492,0,7096,0,10596,0,299,2313368,1107256,1191901,31966,11081,D3,P3,21030,75112,2052,3462310,1116,111600,3168,3573910,5091.46,3601.62
364
+ 13/05/2023,3712,1231,1344557,3399,100714,59509032,0,3986,0,4282,0,9753,0,366,3067797,1388882,1403486,38518,10762,D3,P3,16294,64652,1611,2693420,827,82700,2438,2776120,3925.27,2780.04
365
+ 14/05/2023,3719,1241,1520157,3491,120162,49538293,0,1891,0,3002,0,7363,0,278,3140882,1429620,2518831,44744,12151,D3,P3,13378,55706,1428,2535460,765,76500,2193,2611960,3658.41,2543.11
366
+ 15/05/2023,7735,2663,2102264,5175,106903,46609819,0,2518,0,4548,0,16201,0,880,2916228,1288902,2456845,36269,15290,D3,P3,21857,67301,2149,3844360,1075,107500,3223,3951760,5540.69,3945.07
367
+ 16/05/2023,9409,3206,2134290,5636,88201,9662393,0,2247,0,6690,0,15031,0,1588,3161940,1370882,2403330,37393,14187,D3,P3,26562,53380,2486,4026650,1251,125100,3736,4150900,6839.28,4817.99
368
+ 17/05/2023,8409,2785,1473128,4336,56382,2232239,0,2557,0,6401,0,8946,0,322,3199527,1379566,2608845,39190,12591,D3,P3,21930,41033,2100,3675940,1126,112600,3226,3788540,6156.6,4185.47
369
+ 18/05/2023,8364,2873,1733275,5009,38145,7321146,0,2912,0,7286,0,14366,0,660,2623727,1115471,1723470,36020,12100,D3,P3,21813,40251,1987,3528210,1240,124000,3227,3652210,6388.27,4150.71
370
+ 19/05/2023,6432,2050,1784426,5063,23340,8715910,0,3934,0,6035,0,20378,0,362,2995998,1287313,1959870,36885,12848,D3,P3,19874,38360,1888,3663690,1140,114000,3027,3777590,5981.25,3891.85
371
+ 20/05/2023,5428,1724,1635604,4408,34693,8783612,0,3318,0,4714,0,21030,0,236,2996479,1326416,1903323,31048,12256,D3,P3,17568,33060,1691,3342720,931,93100,2623,3437270,5113.91,3453.26
372
+ 21/05/2023,5657,1807,1788487,4492,24812,5015214,0,2253,0,4227,0,11656,0,494,3167634,1309450,3651254,33361,13073,D3,P3,14766,28367,1461,2940020,800,80000,2261,3020020,4874.35,3300.96
373
+ 22/05/2023,5768,2036,2176947,5688,25298,3002995,0,2739,0,8313,0,25663,0,1147,3573865,1548365,3939226,33410,14092,D3,P3,21520,40205,1854,3533540,1097,109700,2951,3643240,6425.41,4211.67
374
+ 23/05/2023,5051,1720,2359219,6966,24773,3005057,0,4738,0,13827,0,47900,0,965,3248157,1376975,3631390,35016,13025,D3,P3,29860,51811,2527,5012370,1339,133900,3866,5146270,7978.08,5238.68
375
+ 24/05/2023,6078,1977,1612918,4924,24591,2833280,0,4816,0,12417,0,94489,0,1254,3572793,1550315,3532105,37491,12546,D3,P3,41297,68099,2993,5666720,1655,165500,4648,5832220,8715.48,5761.11
376
+ 25/05/2023,6547,2075,1468456,3624,19705,2771412,0,5070,0,7395,0,70016,0,762,3164337,1353382,3253308,34658,13154,D3,P3,33436,56714,2588,5066960,1509,150900,4097,5217860,7939.09,5062.98
377
+ 26/05/2023,3719,1189,1770048,4874,16879,2875657,0,2855,0,6964,0,29015,0,627,2989794,1248779,3345390,38267,12788,D3,P3,22185,40261,2101,4010930,1130,113000,3231,4123930,6785.57,4495.67
378
+ 27/05/2023,3620,1145,1900387,5061,14156,2663378,0,3295,0,4472,0,5625,0,1473,3576647,1527545,3694843,40685,12844,D3,P3,13490,26751,1407,2592840,756,75600,2163,2668440,5325.41,3549.17
379
+ 28/05/2023,4195,1302,2026053,5703,12334,2609966,0,2190,0,3737,0,5030,0,1401,3376177,1447089,2563297,42359,13543,D3,P3,13124,25607,1374,2558180,722,72200,2096,2630380,5282.85,3554.29
380
+ 29/05/2023,5265,1798,2328823,6483,14783,2537637,0,3954,0,5211,0,221,0,1575,3765997,1720747,2865333,39579,8116,D3,P3,15619,30688,1585,2979010,785,78500,2370,3057510,5961.63,4097.14
381
+ 30/05/2023,3879,1366,2294654,6008,15979,2489630,0,4465,0,6041,0,6,0,1192,3790830,1751416,2822819,37234,8830,D3,P3,17258,32693,1773,3270270,900,90000,2673,3360270,6752.47,4596.75
382
+ 31/05/2023,3933,1348,1645187,4081,14208,2337652,0,3797,0,4794,0,6,0,888,4151434,1953620,2714074,45856,6861,D3,P3,16458,31379,1688,3065730,924,92400,2612,3158130,6598.66,4373.22
383
+ 1/6/2023,4817,1530,1862175,4841,48192,3241822,0,3060,0,4802,0,12820,0,1137,4151797,1903421,2255850,51175,7095,D3,P3,17582,34622,1700,3231430,909,90900,2609,3322330,6342.48,4257.19
384
+ 2/6/2023,5733,1800,966546,2646,43573,4582872,0,1563,0,10678,0,46810,0,1309,4313201,2009602,2074692,47378,6120,D3,P3,25710,47869,2271,4131170,1130,113000,3401,4244170,6992.72,4747.36
385
+ 3/6/2023,4142,1290,2445721,11111,90587,4764628,0,2176,0,5144,0,27735,0,518,4514302,2083217,2095544,58527,5748,D3,P3,19247,37244,1905,3615570,961,96100,2866,3711670,5996.2,4065.63
386
+ 4/6/2023,5143,1613,2296690,6790,40929,4717779,0,1280,0,4237,0,5606,0,325,4179140,1889452,2152476,45239,6093,D3,P3,13474,29405,1475,2776480,755,75500,2230,2851980,5219.47,3571.73
387
+ 5/6/2023,5384,1832,3509278,8938,56272,19979584,0,1377,0,11493,0,25647,0,579,3683204,1641254,3616732,40356,6453,D3,P3,22558,54639,2114,4004520,1128,112800,3242,4117320,6672.4,4468.93
388
+ 6/6/2023,4802,1594,3216944,7861,20049,33102789,0,1485,0,9086,0,36532,0,545,3822453,1716540,3687300,53347,6334,D3,P3,26643,69935,2358,4505090,1222,122200,3580,4627290,6855.89,4686.82
389
+ 7/6/2023,5072,1648,2143372,5356,22553,21321547,0,1576,0,7213,0,21215,0,628,4178339,1811963,2354753,51632,6259,D3,P3,22242,56660,2125,3900920,1184,118400,3309,4019320,6611.5,4370.78
390
+ 8/6/2023,4444,1465,3190766,8024,53653,10254268,0,2046,0,10491,0,19549,0,769,3941272,1738344,2283350,59291,6775,D3,P3,23293,50105,2238,4145770,1270,127000,3508,4272770,6851.85,4515.66
391
+ 9/6/2023,4818,1605,3278715,9328,18347,4890758,0,1925,0,8360,0,32385,0,1732,3969227,1777864,2353376,52000,6026,D3,P3,25950,50611,2404,4657210,1315,131500,3719,4788710,6881.12,4639.8
392
+ 10/6/2023,3465,1207,2887842,8529,725,5489947,0,1230,0,5401,0,37954,0,2136,4458593,2061762,2535928,66567,5554,D3,P3,24413,47973,2370,4584570,1225,122500,3595,4707070,6334.68,4283.38
393
+ 11/6/2023,4727,1501,3149290,8114,738,5313957,0,1839,0,8198,0,32493,0,1533,4442610,2006438,2183963,47655,6008,D3,P3,23656,46275,2220,4441870,1183,118300,3403,4560170,6134.11,4098
394
+ 12/6/2023,6437,2208,4416005,12345,149561,5298884,0,1905,0,8542,0,101079,0,472,4645531,1995891,3301882,38760,4966,D3,P3,44382,76997,3520,6853780,1782,178200,5302,7031980,8549.02,5779.3
395
+ 13/06/2023,3556,1254,4626697,12984,258088,5952266,0,2095,0,10415,0,59770,0,1016,4508060,1912958,3440789,47281,4630,D3,P3,35764,67060,2737,5184020,1530,153000,4266,5335600,7908.1,5200.7
396
+ 14/06/2023,3178,1060,3389530,10298,685692,10454400,0,2258,0,24457,0,16016,0,1101,4573214,1920050,3160905,41549,5083,D3,P3,27677,56158,2257,4257990,1244,124400,3501,4382390,7187.71,4826.11
397
+ 15/06/2023,2981,999,3131350,10791,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4075106,1690702,3267810,50496,5037,D3,P3,23775,50354,2201,4212820,1215,121500,3416,4334320,7339.75,4890.1
398
+ 16/06/2023,2705,947,2923279,11124,1166424,11840950,0,1780,0,8938,0,24339,0,966,4533368,1939737,2881833,41872,4604,D3,P3,22957,49677,2225,4445430,1154,115400,3379,4560830,6663.77,4416.03
399
+ 17/06/2023,3697,1154,2955836,10440,807683,9748201,0,2139,0,5741,0,54129,0,766,4958344,2059487,3183051,52618,3675,D3,P3,26623,53187,2434,4755560,1286,128600,3723,4890110,6983.5,4694.41
400
+ 18/06/2023,3229,1080,3280006,12373,116340,8176712,0,1481,0,4741,0,16724,0,864,4270249,1735486,3251229,39780,3696,D3,P3,16690,36522,1715,3294460,936,93600,2651,3388060,5614.57,3749.6
401
+ 19/06/2023,3082,1003,6545797,24462,55763,4841897,0,2098,0,10520,0,26558,0,2211,4137846,1743715,2680413,43156,4347,D3,P3,25736,50759,2343,4515000,1244,124400,3587,4639400,7090.09,4789.96
402
+ 20/06/2023,2422,857,6734594,28910,52166,4718912,0,2205,0,10284,0,30610,0,1002,4218772,1771102,2058734,42288,4260,D3,P3,27941,52107,2478,4829920,1398,139800,3876,4969720,7584.9,4974.28
403
+ 21/06/2023,3366,1132,4784180,17247,52817,5971594,0,3387,0,9277,0,41697,0,645,4113884,1743016,2111350,44159,4193,D3,P3,28338,53853,2376,4353550,1357,135700,3733,4489250,7214.21,4702.88
404
+ 22/06/2023,2841,924,3300680,13360,29784,6803330,0,4064,0,7068,0,68638,0,481,3738171,1533407,1597072,35381,4173,D3,P3,34683,62182,2532,4863520,1434,143400,3966,5006920,7223.75,4679.68
405
+ 23/06/2023,2474,805,2284446,9012,80066,6833289,0,3274,0,7379,0,13501,0,721,4479743,1889155,1647740,39089,3640,D3,P3,16506,35549,1530,2980550,888,88800,2418,3069350,5295.75,3457.41
406
+ 24/06/2023,2462,814,1947190,7247,50309,6526903,0,2767,0,4703,0,8438,0,616,3758421,1565736,1648519,46332,3834,D3,P3,13804,31588,1381,2698000,788,78800,2169,2776800,4822.39,3136
407
+ 25/06/2023,2082,679,3560248,14850,50806,6368664,0,2767,0,4414,0,5346,0,628,4038846,1700182,2514456,43065,4201,D3,P3,13435,30121,1424,2782640,778,77800,2202,2860440,5082.66,3353.86
408
+ 26/06/2023,2399,839,5999950,28401,23209,10788275,0,3699,0,13383,0,13592,0,790,3427918,1403888,3598236,33883,4642,D3,P3,21114,49622,1959,3810990,1175,117500,3134,3928490,6965.39,4504.75
409
+ 27/06/2023,2307,804,5005495,18260,81344,14103220,0,7082,0,8898,0,40917,0,945,3819654,1523667,3556028,35326,4628,D3,P3,32019,65348,2877,5691820,1595,159500,4472,5851320,9589,6333.48
410
+ 28/06/2023,2215,759,3721084,11248,20153,10547995,0,8387,0,7120,0,39693,0,944,3671994,1568555,1397196,33212,2998,D3,P3,30267,63086,2863,5931970,1516,151600,4379,6083570,8919.81,5942.75
411
+ 29/06/2023,2013,706,3918049,10226,155296,8525871,0,10096,0,5693,0,24049,0,1512,3937747,1585655,3393043,30700,2519,D3,P3,22893,54097,2125,4215060,1132,113200,3257,4328260,7178.85,4806.94
412
+ 30/06/2023,1258,454,3088874,7943,902115,10945715,0,8904,0,9611,0,62404,0,1029,4945464,1946944,1835310,52445,2839,D3,P3,30707,67849,2616,5112840,1397,139700,4013,5252540,7664.09,5203.16
413
+ 1/7/2023,1641,539,3872657,12034,191537,12141356,0,4956,0,6049,0,31194,0,923,5328149,2224200,2123805,56724,2513,D3,P3,22229,54353,2266,4505840,1205,120500,3471,4626340,6983.83,4746.37
414
+ 2/7/2023,1336,485,5799582,17238,576858,12180985,0,4148,0,4670,0,4766,0,617,4527404,1997256,2038953,50510,21201,D3,P3,15205,43684,1672,3328290,886,88600,2559,3416990,5952.59,4038.91
415
+ 3/7/2023,2712,924,9986061,28191,442261,14059535,0,5347,0,7408,0,19028,0,1044,4179823,1854231,2234940,57543,14473,D3,P3,22798,57392,2425,4796940,1308,130800,3732,4925290,7701.44,5182.84
416
+ 4/7/2023,4137,1419,4717456,14519,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4449073,1959412,2350308,49085,9854,D3,P3,23585,60143,2220,4262060,1327,132700,3547,4394760,7689.38,5021.95
417
+ 5/7/2023,4166,1422,4779589,12676,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4464681,1969744,2390838,41411,12751,D3,P3,22847,61021,2348,4359400,1422,142200,3769,4497600,7976.49,5170.89
418
+ 6/7/2023,4182,1444,4939385,12222,2364811,15879491,0,6575,0,8461,0,18225,0,997,4490815,1942923,2239375,44808,16216,D3,P3,23716,60282,2602,4960450,1543,154300,4145,5114750,8225.73,5423.76
419
+ 7/7/2023,3497,1181,3121447,7534,1063284,17341347,0,6025,0,8113,0,25962,0,659,4891573,2128787,1976413,57373,12464,D3,P3,23336,58252,2335,4783910,1269,126900,3604,4910810,7182.26,4846.37
420
+ 8/7/2023,2760,856,3295227,9788,1119268,19207341,0,4102,0,6195,0,40506,0,832,5039604,2277255,2330435,44052,15163,D3,P3,22278,62471,2128,4352160,1191,119100,3319,4471260,6706.12,4485.38
421
+ 9/7/2023,2809,875,3913741,11815,749310,25182206,0,6420,0,5222,0,49626,0,718,4669470,2144473,3908306,49659,11716,D3,P3,24736,69003,2620,5573560,1325,132500,3945,5706060,7673.85,5278.59
422
+ 10/7/2023,4312,1489,5972974,18402,1511035,25950979,0,9842,0,10638,0,36204,0,935,4584106,2019220,4391654,52303,12983,D3,P3,28497,78251,2578,5157430,1419,141900,3997,5299330,8174.81,5453.8
423
+ 11/7/2023,4579,1550,4999618,16469,559119,23938153,0,11688,0,36570,0,25216,0,1289,4458364,1932300,4150666,47979,12292,D3,P3,28688,77223,2707,5384090,1483,148300,4190,5532390,8594.12,5787.78
424
+ 12/7/2023,4079,1418,4465722,13191,583520,25196511,0,4610,0,9813,0,20388,0,1210,4558876,2000168,4109583,54631,12366,D3,P3,25749,73523,2403,4926480,1410,141000,3813,5067480,8000.73,5259.61
425
+ 13/07/2023,3719,1260,4635033,12302,903614,25720336,0,7867,0,6792,0,22248,0,857,4596184,1957206,3729970,48474,11017,D3,P3,22447,69283,2134,4261960,1312,131200,3447,4393760,7385.89,4769.15
426
+ 14/07/2023,3632,1224,3441594,9800,1566300,28606996,0,6726,0,6172,0,14670,0,432,4683387,2007387,3912229,52588,10079,D3,P3,19225,67928,2002,3875450,1077,107700,3079,3983150,6615.15,4505.74
427
+ 15/07/2023,2909,941,6025085,21326,1836196,28705476,0,5705,0,4369,0,31202,0,595,5008167,2251661,3727627,58143,10214,D3,P3,19533,64001,2026,4112810,1066,106600,3093,4220310,6115.73,4122.89
428
+ 16/07/2023,2818,853,7339565,26586,4043959,26752554,0,7733,0,3961,0,27180,0,1082,4716541,2092258,2114014,59204,11281,D3,P3,18871,60797,1956,3715100,1126,112600,3084,3832400,6216.99,4066.5
429
+ 17/07/2023,4420,1486,9638491,32269,819444,29437537,0,11485,0,5220,0,66236,0,2418,4359325,1937825,1989872,55815,11896,D3,P3,35493,89662,2771,5539890,1521,152100,4292,5691990,8025.2,5388.69
430
+ 18/07/2023,4574,1551,9498457,31230,1206114,29164369,0,5012,0,7146,0,47074,0,2358,4882304,2163458,2157773,69573,12604,D3,P3,32238,84091,2687,5214920,1329,132900,4016,5347820,7833.63,5336.47
431
+ 19/07/2023,4632,1537,9742535,26935,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4613422,2080215,1981362,67495,12116,D3,P3,23193,69138,2342,4581910,1084,108400,3426,4690310,7118.68,4991.3
432
+ 20/07/2023,4891,1632,7630122,20720,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4484291,1922090,1663127,75312,12252,D3,P3,23193,63445,2209,4471970,995,99500,3255,4576570,6700.79,4599.1
433
+ 21/07/2023,3978,1378,7284968,21477,2456715,17869335,0,6360,0,10877,0,11431,0,769,4519305,1975730,1686467,68931,10065,D3,P3,21478,57996,2115,4257360,1006,100600,3121,4357960,6467.01,4497.43
434
+ 22/07/2023,3151,978,5638955,16181,2015345,12808440,0,7097,0,5145,0,13811,0,699,4689346,2086993,1861883,71898,9081,D3,P3,17602,50209,1897,3876970,830,83000,2727,3959970,5812.35,4126.62
435
+ 23/07/2023,2905,986,6133144,16089,881691,11267535,0,5593,0,4746,0,68021,0,514,4242878,1843843,1681215,61164,10797,D3,P3,25804,58279,2442,5168300,1161,116100,3603,5284400,6622.56,4639.27
436
+ 24/07/2023,4606,1651,8830736,21931,189913,35658281,0,8836,0,6040,0,64066,0,1626,3943001,1708849,1900126,59494,10236,D3,P3,31953,73505,2898,6111230,1424,142400,4321,6253530,8030.22,5492.47
437
+ 25/07/2023,4414,1597,7750251,15384,3348941,25011847,0,10262,0,9572,0,15072,0,916,3976490,1729916,1911109,68826,11468,D3,P3,26162,65005,2440,4822810,1154,115400,3594,4938210,7092.81,4965.39
438
+ 26/07/2023,4488,1530,8125332,16391,1040452,24380635,0,9947,0,16453,0,38777,0,1551,3837786,1680967,1856885,74924,13290,D3,P3,31894,69746,2797,5552460,1348,134800,4147,5687460,7359.12,5027.76
439
+ 27/07/2023,4105,1494,8054962,14724,220302,13070502,0,6758,0,8841,0,20622,0,1313,3636297,1544742,1772602,63935,11680,D3,P3,24634,57255,2498,5018670,1196,119600,3694,5138270,7106.66,4875.99
440
+ 28/07/2023,3743,1318,6955526,11566,3991586,5347413,0,10451,0,8496,0,20184,0,1563,3890784,1680538,1608577,73120,11390,D3,P3,22265,50660,2204,4515740,1054,105400,3258,4621140,6441.87,4432.07
441
+ 29/07/2023,3395,1192,5132501,9837,1349895,4441709,0,7115,0,5449,0,18983,0,1129,4295602,1813637,1824777,80511,11911,D3,P3,17626,42341,1930,3807270,860,86000,2790,3893270,5519.71,3922.54
442
+ 30/07/2023,2746,903,4903153,11018,710000,4431986,0,8491,0,4599,0,24834,0,1109,3924352,1733790,1740605,72221,11440,D3,P3,17619,43309,1942,3937090,834,83400,2776,4020490,5556.3,3945.89
443
+ 31/07/2023,4208,1476,6832832,19648,1721973,4079656,0,7754,0,7818,0,27918,0,2050,3760475,1501134,1957900,62124,11605,D3,P3,22728,51399,2256,4604950,1046,104600,3302,4709550,6481.79,4556.75
444
+ 1/8/2023,4203,1489,6398210,15890,2250090,5457683,0,7588,0,7948,0,61894,0,1248,3687038,1439092,1774701,61448,11492,D3,P3,31009,67515,2609,5471270,1309,130900,3918,5602170,6825.97,4671.87
445
+ 2/8/2023,4285,1515,5402871,14825,785167,6582085,0,6079,0,7236,0,79041,0,1345,3807266,1493340,2025308,54506,11515,D3,P3,34034,74123,2858,5856910,1360,136000,4218,5992910,7171.23,4989.3
446
+ 3/8/2023,4667,1744,4724924,8903,1111815,10407793,0,9077,0,7117,0,31714,0,1983,3797879,1479623,1718831,52587,11408,D3,P3,23978,62504,2404,4832400,1095,109500,3498,4941800,6670.71,4627.48
447
+ 4/8/2023,4201,1562,3732952,9116,4574481,10660977,0,8436,0,6970,0,25097,0,1055,3814852,1466211,1374674,57482,10785,D3,P3,21714,62922,2226,4561560,975,97500,3201,4659060,6133.71,4366.77
448
+ 5/8/2023,3080,1110,3310732,9884,3460283,11580456,0,5735,0,5049,0,5911,0,704,4048945,1601234,1442690,65158,9942,D3,P3,13792,52995,1578,3188640,720,72000,2298,3260640,4760.04,3375.44
449
+ 6/8/2023,2809,979,4153998,11663,5103054,8381689,0,4868,0,4184,0,28658,0,637,4040770,1250223,1844909,47698,10816,D3,P3,17706,56827,1841,3921270,842,84200,2683,4005470,5062.91,3520.39
450
+ 7/8/2023,3522,1186,3164171,10000,4137349,8709017,0,6112,0,6640,0,43866,0,1285,3928811,1288638,1861166,44623,11648,D3,P3,26772,71580,2456,4923260,1132,113200,3587,5034960,6580.87,4648.84
451
+ 8/8/2023,4111,1495,6020074,15008,2923076,5012245,0,6684,0,6961,0,12257,0,3038,3921429,1094791,2059462,48047,10379,D3,P3,22363,60212,2075,4138870,971,97100,3046,4235970,6286.57,4418.71
452
+ 9/8/2023,3609,1285,5616011,13195,2483117,3900778,0,8177,0,6447,0,12774,0,1309,3322165,452000,2262292,52219,11047,D3,P3,21099,53059,2067,4030270,1010,101000,3077,4131270,6309.32,4273.88
453
+ 10/8/2023,3872,1330,5270940,11342,1305507,3614496,0,6927,0,6602,0,21830,0,986,2868345,452896,1541791,46720,10556,D3,P3,22515,52055,2216,4848640,974,97400,3190,4946040,6281.59,4498.26
454
+ 11/8/2023,3673,1257,4485834,10445,3562053,5521177,0,5810,0,13751,0,5797,0,751,3242607,511016,1679989,47262,10344,D3,P3,17086,46491,1551,3242370,671,67100,2222,3309470,4608.96,3355.58
455
+ 12/8/2023,2744,960,3946512,10052,4015316,5813616,0,6205,0,10379,0,9890,0,532,3761072,595191,1931989,54787,9210,D3,P3,15949,46498,1376,3113130,639,63900,2016,3177130,4121.65,2907.82
456
+ 13/08/2023,2418,775,5051792,11809,1869057,6348414,0,4093,0,5187,0,21320,0,399,3279816,503805,2171335,55136,10546,D3,P3,14745,44224,1327,2888900,648,64800,1975,2953700,3905.29,2752.8
457
+ 14/08/2023,3551,1196,4839009,11805,1765326,3758610,0,6170,0,7226,0,19575,0,706,2974893,427940,1822890,49127,11042,D3,P3,20336,49993,1770,3798710,748,74800,2518,3873510,5195.83,3786.85
458
+ 15/08/2023,3430,1312,6520709,24857,1792924,1852314,0,6063,0,9302,0,34681,0,778,3080012,462344,1935145,57900,11083,D3,P3,24449,48710,1946,4332210,807,80700,2752,4412810,5367.05,3930.18
459
+ 16/08/2023,3253,1175,4844378,27290,3478033,1293346,0,5884,0,8280,0,29077,0,1055,3150093,468159,2094524,58937,11823,D3,P3,23892,46995,1911,3996580,780,78000,2691,4074580,5452.88,3979.2
460
+ 17/08/2023,3714,1417,4702754,23408,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3071572,444690,1961293,58681,10987,D3,P3,21265,42100,1700,3517380,704,70400,2404,3587780,5150.22,3718.85
461
+ 18/08/2023,1936,710,4370177,18919,3789636,1020973,0,9525,0,8958,0,32346,0,909,3252966,461174,2031390,61098,10354,D3,P3,20983,41383,1778,3654630,679,67900,2457,3722530,5019.58,3716.93
462
+ 19/08/2023,1998,723,3683868,14860,5187185,1336224,0,8305,0,6265,0,13396,0,1267,3460234,494225,2037289,68988,9709,D3,P3,14640,31119,1331,2887610,528,52800,1860,2943410,4059.2,3012.38
463
+ 20/08/2023,2458,839,5558511,16917,6444084,1333600,0,8083,0,5668,0,9425,0,593,3233047,427550,2093935,58698,11658,D3,P3,13616,29557,1227,2592690,476,47600,1703,2640290,3842.86,2850.38
464
+ 21/08/2023,2316,892,5802540,21997,1578062,1099659,0,9057,0,8434,0,11204,0,597,3110596,442523,1991499,71910,13059,D3,P3,19336,38812,1656,3445610,663,66300,2319,3510210,5100.16,3789.37
465
+ 22/08/2023,2208,845,5006504,13886,598218,939529,0,18631,0,11119,0,18304,0,666,3020862,419659,1960342,66769,12591,D3,P3,21348,42166,1844,3824050,762,76200,2582,3877380,5610.58,4088.17
466
+ 23/08/2023,2104,821,5240143,16309,1941212,2081327,0,17073,0,8077,0,6042,0,709,2634348,409468,1726842,53998,13783,D3,P3,18864,38949,1513,3153720,655,65500,2165,3219310,4984.78,3596.01
467
+ 24/08/2023,2011,685,5623870,14314,380971,2132605,0,13223,0,7340,0,11449,0,1774,2244344,385012,1409286,55699,13185,D3,P3,18821,38282,1665,3378840,678,67800,2358,3474730,5209.76,3795.85
468
+ 25/08/2023,1889,680,4674166,13506,1119189,1818097,0,33200,0,7250,0,16577,0,3622,2405697,395219,1564070,61103,13348,D3,P3,18364,37536,1863,3939560,638,63800,2501,4003360,5070.56,3850.47
469
+ 26/08/2023,1229,379,5475213,18030,476090,1048919,0,15316,0,4976,0,16625,0,3546,2662312,434769,1789446,61768,13346,D3,P3,16076,32992,1816,3388030,606,60600,2422,3448630,4877.02,3729.33
470
+ 27/08/2023,1333,486,5591938,13138,956722,732493,0,12952,0,4227,0,19562,0,2354,2470188,417919,1980888,53707,14151,D3,P3,14834,30563,1572,2979370,536,53600,2108,3032970,4232.88,3241.64
471
+ 28/08/2023,2031,760,7120359,17304,592505,571748,0,44816,0,8728,0,19999,0,3813,2357294,420574,1878047,50335,13442,D3,P3,20994,42982,1970,3877550,642,64200,2612,3941750,5610.5,4325.83
472
+ 29/08/2023,1560,550,6349650,18074,395464,276869,0,217642,0,8742,0,36555,0,2778,2437012,455532,1707585,52913,12648,D3,P3,25919,51217,2270,4323380,803,80300,3073,4403680,6223.41,4701.59
473
+ 30/08/2023,1788,623,6774580,17019,804715,227676,0,92490,0,7576,0,33376,0,1815,2461827,452647,1924554,57945,12244,D3,P3,24015,48307,2298,4414000,796,79600,3094,4493600,5983.31,4520.44
474
+ 31/08/2023,2251,790,6881955,16586,462096,216142,0,177608,0,7188,0,13212,0,1862,2630688,508779,1691540,44071,12093,D3,P3,17587,35874,1809,3406910,604,60400,2413,3467310,5218.62,4005.29
475
+ 1/9/2023,2763,930,5360505,17680,259775,323504,0,21865,0,7383,0,4899,0,1313,2723715,529388,1841032,48663,11275,D3,P3,13457,29785,1396,2542480,459,45900,1855,2588380,4243.41,3270.46
476
+ 2/9/2023,2597,870,4478842,15289,1226680,320820,0,26924,0,6477,0,4896,0,1454,2929332,613163,1945160,60288,10815,D3,P3,12337,27451,1347,2481120,508,50800,1855,2531920,4227.98,3109.35
477
+ 3/9/2023,2332,762,5174329,13994,449228,288375,0,20423,0,5755,0,10890,0,1494,2516381,558353,1697712,54329,11996,D3,P3,12609,27028,1428,2699310,481,48100,1909,2747410,4177.46,3164.79
478
+ 4/9/2023,3561,1229,5334952,17444,296660,306771,0,324815,0,7849,0,41134,0,2069,2485534,613680,1823512,52578,12787,D3,P3,22283,45146,2065,3908960,791,79100,2855,3987700,5743.35,4264.57
479
+ 5/9/2023,2261,816,6113505,20426,302910,227998,0,287642,0,7998,0,21025,0,1448,2453507,595873,1648165,49590,11749,D3,P3,19096,40015,1818,3314870,588,58800,2407,3377390,5367.87,4153.87
480
+ 6/9/2023,2868,1031,5558783,13407,1266416,255848,0,203777,0,8887,0,9020,0,933,2766708,736889,1987155,47189,10851,D3,P3,14311,31495,1502,2764430,499,49900,2001,2814330,4575.2,3510.97
481
+ 7/9/2023,2394,832,4907653,9041,191893,285511,0,202017,0,8317,0,6879,0,801,2616416,630668,1712157,47089,11632,D3,P3,13483,29283,1544,2846790,463,46300,2007,2893090,4770.64,3739.02
482
+ 8/9/2023,2689,910,4752031,8867,157343,302141,0,201772,0,8717,0,5684,0,1428,2705167,791338,1852090,43707,10493,D3,P3,13830,29726,1531,2806450,518,51800,2049,2858250,4807.58,3697.23
483
+ 9/9/2023,2204,752,3975657,10022,227113,245700,0,201776,0,7299,0,4098,0,758,2929279,827015,2001938,50033,10082,D3,P3,12284,26212,1414,2674080,433,43300,1847,2717380,4310.87,3354.94
484
+ 10/9/2023,2167,743,4243960,10399,270612,291468,0,201256,0,6099,0,8097,0,809,2352670,1241029,1966290,41767,10185,D3,P3,12594,26398,1498,2834900,435,43500,1933,2878400,4460.59,3531.69
485
+ 11/9/2023,3381,1227,4492340,10684,1192346,154867,0,202476,0,8393,0,6493,0,838,2573007,1455728,1830559,39596,12910,D3,P3,15510,32142,1544,2881650,449,44900,1992,2923700,4715.59,3736.66
486
+ 12/9/2023,2511,884,4936079,10015,199137,170680,0,50740,0,8506,0,26721,0,1085,2527461,1481401,1856155,40974,11883,D3,P3,22786,42733,2027,4286230,326,32600,2353,4318830,5172.4,4510.57
487
+ 13/09/2023,2143,778,5115564,10338,292239,238162,0,2408,0,7172,0,36811,0,836,2621020,1580825,1962940,39948,11634,D3,P3,22084,41155,1880,3809460,281,28100,2161,3837560,4765.04,4181.98
488
+ 14/09/2023,2307,798,4859067,12717,1181194,308251,0,948,0,7404,0,38152,0,1282,2677877,1397139,1251585,46129,10253,D3,P3,21377,40308,1959,3742130,550,55000,2509,3797130,5413.06,4301.68
489
+ 15/09/2023,2467,882,4260164,9702,399193,291844,0,756,0,6932,0,16060,0,2982,2751748,1416780,1269521,57909,10048,D3,P3,16118,32895,1659,3149040,526,52600,2185,3201640,4920.59,3802.04
490
+ 16/09/2023,2076,687,3350011,7707,620978,196303,0,663,0,6018,0,9889,0,1188,3083552,1564491,1439332,61159,9435,D3,P3,12830,26945,1488,2798420,446,44600,1934,2843020,4519.52,3564.8
491
+ 17/09/2023,2467,802,4503316,11119,581720,236009,0,637,0,4814,0,10024,0,2464,2935930,1503370,1649587,48796,10073,D3,P3,12357,25262,1396,2560250,455,45500,1851,2605750,4246.67,3287.31
492
+ 18/09/2023,2910,1024,5568066,14302,184276,143660,0,888,0,6922,0,10381,0,1767,2373681,1330212,1479501,51224,10488,D3,P3,16441,33582,1727,3152630,572,57200,2300,3209930,5491.87,4171.85
493
+ 19/09/2023,3252,1309,6105220,12193,208312,187769,0,1464,0,5210,0,8092,0,1504,2373344,1285881,1407015,40642,10547,D3,P3,17770,36578,1743,3229930,653,65300,2395,3291230,5666.71,4236.34
494
+ 20/09/2023,2796,1185,6055420,14003,291395,272928,0,1077,0,4246,0,10472,0,1830,2565110,1425196,1460886,48962,10318,D3,P3,16656,34188,1627,3048960,738,73800,2365,3121460,5577.7,3950.97
495
+ 21/09/2023,2208,878,5225528,8679,697480,160425,0,1033,0,6726,0,13928,0,1357,2686089,1447330,1236533,49940,10259,D3,P3,17253,34210,1912,3553480,811,81100,2723,3634580,6248.63,4440.07
496
+ 22/09/2023,1734,783,4373391,8141,2220006,88968,0,738,0,9534,0,8771,0,1690,2460283,1353647,1258771,45467,9910,D3,P3,14958,31389,1714,3084570,758,75800,2472,3160370,5984.05,4280.38
497
+ 23/09/2023,1190,492,4948823,10035,2432739,154849,0,702,0,8285,0,4369,0,806,2740252,1531672,1407980,51747,8665,D3,P3,12641,27336,1443,2653190,652,65200,2095,2718390,5094.46,3633.56
498
+ 24/09/2023,1124,496,6239124,10744,248085,231243,0,477,0,8032,0,8640,0,1449,2648532,1476875,1294436,36638,10410,D3,P3,12153,26113,1395,2618830,621,62100,2016,2680930,4558.91,3242.77
499
+ 25/09/2023,2358,1041,5325249,9804,251517,447312,0,591,0,11299,0,21103,0,1135,2371891,1333464,1222194,36894,9191,D3,P3,18608,38878,2041,3740860,897,89700,2938,3830560,6554.2,4744.62
500
+ 26/09/2023,2092,994,5361926,13223,90916,351820,0,910,0,10598,0,27697,0,2803,2612585,1502573,1256804,33211,8893,D3,P3,21214,41166,2128,3878240,935,93500,3063,3971740,6565.1,4696.86
501
+ 27/09/2023,1835,792,4600061,14060,728920,347014,0,1111,0,8811,0,104094,0,1780,2488689,1390273,1203937,33935,8769,D3,P3,37289,65137,2933,5530540,1595,159500,4525,5686340,8073.74,5545.54
502
+ 28/09/2023,1787,807,4114657,9434,84913,564139,0,279332,0,6975,0,51946,0,2516,2290090,1309586,1316086,32443,8606,D3,P3,25651,47307,2343,4257450,1199,119900,3542,4377350,7151.36,4963.98
503
+ 29/09/2023,1513,641,4477584,8505,211297,372199,0,443,0,4039,0,4466,0,1774,2429135,1379398,1425850,31700,7184,D3,P3,12276,26946,1488,2459350,613,61300,2101,2520650,5148.56,3726.34
504
+ 30/09/2023,1127,478,4089760,9316,222854,364180,0,517,0,3251,0,13297,0,1425,1049942,435407,548780,10869,4505,D3,P3,12905,27091,1533,2701900,640,64000,2173,2765900,5022.4,3685.32
505
+ 1/10/2023,1021,436,748856,2639,301970,224135,0,846,0,2731,0,7574,0,962,935755,413098,1084400,13147,5335,D3,P3,9103,18479,1165,2022810,467,46700,1632,2069510,3823.3,2818.63
506
+ 2/10/2023,1673,764,1692932,4211,387802,237932,0,1564,0,12820,0,9400,0,1463,877002,383352,1016934,14302,5965,D3,P3,12307,24110,1290,2265000,565,56500,1855,2321500,4314.73,3091.4
507
+ 3/10/2023,1516,725,1757367,3947,568156,171003,0,1739,0,21454,0,5276,0,1640,833524,365270,973716,14227,5936,D3,P3,12568,24900,1344,2390760,645,64500,1989,2455260,4686.71,3259.46
508
+ 4/10/2023,1786,763,1733340,3119,567654,129402,0,1726,0,15833,0,13543,0,2940,836392,368220,1029847,13931,5864,D3,P3,13780,26581,1383,2427230,695,69500,2078,2496730,4764.92,3278.39
509
+ 5/10/2023,1986,861,1671129,3736,504268,159069,0,1747,0,24285,0,8234,0,3163,830805,380396,476125,13399,5529,D3,P3,12797,24819,1428,2572910,640,64050,2067,2626960,4940.4,3504.67
510
+ 6/10/2023,1774,753,1348401,2784,702326,205479,0,1686,0,15228,0,12269,0,2107,817142,382879,504402,11840,5476,D3,P3,11345,22554,1268,2317850,601,60300,1869,2378150,4247.46,3014.11
511
+ 7/10/2023,1150,416,1175733,2242,359848,180366,0,1446,0,19417,0,27951,0,2050,921412,418533,520370,11215,5083,D3,P3,14047,25738,1516,3012040,684,68550,2200,3080590,4256.92,3052.07
512
+ 8/10/2023,999,337,1296701,2609,662748,293989,0,1415,0,14589,0,18476,0,1786,768086,352949,357821,12788,5550,D3,P3,11419,21977,1320,2426760,572,57400,1892,2484160,4025.59,2933.34
513
+ 9/10/2023,772,289,1942734,4167,3096792,191352,0,1855,0,24331,0,21658,0,1757,653538,261410,590317,14449,6333,D3,P3,14624,27809,1367,2649310,715,73600,2082,2722910,4326.63,2956.14
514
+ 10/10/2023,737,241,1911227,4238,565419,164827,0,2101,0,11526,0,9057,0,2720,734200,300476,568450,13952,6145,D3,P3,12640,24537,1376,2459930,653,68350,2029,2528280,4537.77,3219.59
515
+ 11/10/2023,681,256,2171216,4714,503802,216630,0,1921,0,7255,0,7549,0,2025,958835,399349,595481,12432,5599,D3,P3,11486,22322,1319,2395980,638,66400,1958,2463820,4317.3,3006.02
516
+ 12/10/2023,673,240,1820266,4067,233553,161215,0,8042,0,4686,0,5288,0,1408,861845,336598,557239,13130,5889,D3,P3,9536,18332,1167,1988790,536,56350,1702,2044540,3786.09,2688.23
517
+ 13/10/2023,595,233,1529402,3094,68852,156834,0,7184,0,4986,0,14364,0,1924,801772,317596,563967,12222,5539,D3,P3,12220,23105,1373,2510340,641,66600,2014,2576940,4218.4,2949.55
518
+ 14/10/2023,748,266,1013578,2156,48430,185877,0,3043,0,4287,0,14809,0,2117,929822,362662,603684,11533,5191,D3,P3,11280,21172,1275,2379750,592,62050,1867,2441800,3859.27,2715.54
519
+ 15/10/2023,602,201,1596953,4098,55580,222305,0,12269,0,4366,0,15778,0,1639,891052,327915,425822,13301,6358,D3,P3,10476,19507,1178,2129330,587,60800,1765,2190130,3766.36,2609.81
520
+ 16/10/2023,964,369,2144206,5169,31683,118393,0,6488,0,5537,0,65656,0,1254,842123,317951,810650,16455,7813,D3,P3,23493,39642,2233,4391770,1136,117850,3369,4509620,5998.13,4174.09
521
+ 17/10/2023,1105,415,2112245,5363,69479,70676,0,4964,0,4816,0,18719,0,2353,816941,328053,766996,14912,7402,D3,P3,15733,28542,1531,2735230,779,81300,2310,2816530,5078.87,3496.45
522
+ 18/10/2023,913,348,1892230,4633,451927,111742,0,4068,0,4855,0,32612,0,2028,957593,377866,689470,15228,7272,D3,P3,18694,32354,1918,3636660,883,91900,2801,3728560,5610.31,3986.54
523
+ 19/10/2023,914,302,1550243,3817,100009,183549,0,4309,0,4468,0,68322,0,2169,846076,336810,775970,14394,6925,D3,P3,26120,43767,2170,4171580,1158,120800,3328,4292380,5891.41,4024.57
524
+ 20/10/2023,663,208,1100622,2740,174916,181797,0,3695,0,4056,0,58835,0,1887,910115,366406,653096,15447,6572,D3,P3,22398,38504,2218,4385190,1035,108650,3253,4493840,5680.14,4012.57
525
+ 21/10/2023,559,184,1405730,3216,207981,276329,0,2723,0,3213,0,44899,0,1893,1184901,485051,850250,14780,6181,D3,P3,17236,31207,1638,3121900,793,82100,2431,3204000,4493.8,3159.39
526
+ 22/10/2023,545,198,1467468,3228,520836,253840,0,2213,0,2850,0,27411,0,1911,1154732,423852,1027954,10344,4893,D3,P3,13607,25217,1482,2893810,725,75700,2207,2969510,4332.98,3030.72
527
+ 23/10/2023,625,231,2018062,5517,333114,436011,0,2839,0,3772,0,11121,0,1351,1208181,428535,1111507,11684,6220,D3,P3,12048,23419,1256,2226550,585,61300,1840,2287750,4042.32,2864.75
528
+ 24/10/2023,574,226,1889784,5099,188275,228582,0,2709,0,2462,0,1109,0,1918,1083131,378488,1161439,11452,5728,D3,P3,10595,21221,1092,1909130,407,43350,1499,1952480,3725.66,2756.39
529
+ 25/10/2023,536,184,2276229,5661,77308,332105,0,2708,0,2679,0,525,0,2402,905535,310989,865636,11200,5884,D3,P3,10143,20535,887,1832160,331,37050,1218,1869210,3037.38,2236.69
530
+ 26/10/2023,609,200,1753696,4367,85971,236204,0,2136,0,2300,0,10,0,3842,968078,332008,771447,10098,5558,D3,P3,9900,19640,858,1671270,347,38950,1205,1710220,2995.78,2165.99
531
+ 27/10/2023,563,209,1636932,3338,246909,285904,0,1992,0,2323,0,5,0,2851,1063329,352124,929257,9507,5001,D3,P3,8240,17233,780,1422510,309,35500,1089,1458010,2635.69,1927
532
+ 28/10/2023,450,155,1588245,4276,235960,324079,0,2716,0,1753,0,1,0,2585,1191854,384343,1028724,8578,4958,D3,P3,7529,15744,725,1476840,300,33850,1025,1510690,2588.52,1884.51
533
+ 29/10/2023,309,117,1731474,5065,70210,331208,0,2241,0,1708,0,5,0,3120,1137463,385520,764681,10186,5650,D3,P3,7535,14889,747,1514990,287,32300,1034,1547290,2594.6,1909.86
534
+ 31/10/2023,486,182,2220653,5950,41641,213812,0,149,0,2404,0,15,0,1380,913362,318222,1020094,10416,3703,D3,P3,8678,18059,784,1613510,309,34550,1093,1648060,2844.9,2076.88
535
+ 1/11/2023,296,123,1834772,4275,201158,313487,0,889,0,2485,0,33093,0,2287,862276,316545,798469,11740,3972,D3,P3,16341,28782,1292,2880920,542,58750,1834,2939670,3468.46,2536.62
536
+ 2/11/2023,346,111,1697213,2987,1586296,64435,0,957,0,2130,0,16368,0,3586,840477,298617,830972,10008,3641,D3,P3,12216,22498,1071,2342490,402,43400,1473,2385890,3237.48,2396.17
537
+ 3/11/2023,224,89,1759831,2940,93667,74522,0,962,0,2484,0,14150,0,953,952592,350909,800378,11090,3818,D3,P3,10460,20113,902,1897210,372,40600,1274,1937810,2883.8,2066.5
538
+ 4/11/2023,214,76,1677064,2752,65182,61325,0,1796,0,3084,0,10438,0,1148,957265,344580,821570,11309,4380,D3,P3,8630,17741,757,1590600,290,31650,1047,1622250,2519.34,1826.6
Model_Result_Overview.py ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import subprocess
2
+ # import sys
3
+
4
+ # def install_conda_package(package_name, channel=None):
5
+ # try:
6
+ # if channel:
7
+ # subprocess.check_call([sys.executable, "-m", "conda", "install", "-c", channel, package_name, "-y"])
8
+ # else:
9
+ # subprocess.check_call([sys.executable, "-m", "conda", "install", package_name, "-y"])
10
+ # except subprocess.CalledProcessError as e:
11
+ # # print(f"Failed to install {package_name}: {e}")
12
+
13
+ # # Example usage
14
+ # install_conda_package("plotly-orca", channel="plotly")
15
+
16
+ import streamlit as st
17
+ import pandas as pd
18
+ from sklearn.preprocessing import MinMaxScaler
19
+ import pickle
20
+ import Streamlit_functions as sf
21
+ from utilities import (load_authenticator)
22
+
23
+ from utilities_with_panel import (set_header,
24
+ overview_test_data_prep_panel,
25
+ overview_test_data_prep_nonpanel,
26
+ initialize_data,
27
+ load_local_css,
28
+ create_channel_summary,
29
+ create_contribution_pie,
30
+ create_contribuion_stacked_plot,
31
+ create_channel_spends_sales_plot,
32
+ format_numbers,
33
+ channel_name_formating)
34
+
35
+ import plotly.graph_objects as go
36
+ import streamlit_authenticator as stauth
37
+ import yaml
38
+ from yaml import SafeLoader
39
+ import time
40
+ from datetime import datetime,timedelta
41
+ from pptx import Presentation
42
+ from pptx.util import Inches
43
+ from io import BytesIO
44
+ import plotly.io as pio
45
+ import response_curves_model_quality as rc1
46
+ st.set_page_config(layout='wide')
47
+ load_local_css('styles.css')
48
+ set_header()
49
+
50
+ st.title("Model Result Overview")
51
+ def add_plotly_chart_to_slide(slide, fig, left, top, width, height):
52
+ img_stream = BytesIO()
53
+ pio.write_image(fig, img_stream, format='png')
54
+ slide.shapes.add_picture(img_stream, left, top, width, height)
55
+
56
+
57
+
58
+ def save_table(df,prs):
59
+ # Add a blank slide
60
+ slide = prs.slides.add_slide(prs.slide_layouts[6])
61
+
62
+ rows, cols = df.shape[0] + 1, df.shape[1] # +1 for the header row
63
+ table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(10), Inches(7)).table
64
+
65
+ # Set the header row
66
+ for col_idx, col_name in enumerate(df.columns):
67
+ table.cell(0, col_idx).text = col_name
68
+
69
+ # Add the DataFrame rows to the table
70
+ for row_idx, row in df.iterrows():
71
+ for col_idx, value in enumerate(row):
72
+ # # # print(value)
73
+ if isinstance(value, int):
74
+ table.cell(row_idx + 1, col_idx).text = str(value)
75
+
76
+
77
+ def save_ppt_file(fig1,fig2,fig3,fig4,fig6,fig7,figw,start_date,end_date,shares_df1,shares_df2):
78
+ # Initialize PowerPoint presentation
79
+ prs = Presentation()
80
+
81
+ # save_table(shares_df1,prs)
82
+ # save_table(shares_df2,prs)
83
+ # Slide 1: Model Quality with Chart
84
+ slide_1 = prs.slides.add_slide(prs.slide_layouts[6])
85
+ # title_1 = slide_1.shapes.title
86
+ # title_1.text = "Distribution Of Spends And Prospects"
87
+ # Add the Plotly chart to the slide
88
+ add_plotly_chart_to_slide(slide_1, sf.pie_contributions(start_date,end_date), Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
89
+ add_plotly_chart_to_slide(prs.slides.add_slide(prs.slide_layouts[6]), sf.pie_spend(start_date,end_date), Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
90
+ # Slide 2: Media Data Elasticity
91
+ slide_2 = prs.slides.add_slide(prs.slide_layouts[6])
92
+ # title_2 = slide_2.shapes.title
93
+ # title_2.text = "Media Contribution"
94
+ add_plotly_chart_to_slide(slide_2, fig2, Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
95
+ slide_3 = prs.slides.add_slide(prs.slide_layouts[6])
96
+ # title_3 = slide_3.shapes.title
97
+ # title_3.text = "Media Spends"
98
+ add_plotly_chart_to_slide(slide_3, fig3, Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
99
+ slide_4 = prs.slides.add_slide(prs.slide_layouts[6])
100
+ # title_4 = slide_4.shapes.title
101
+ # title_4.text = "CPP Distribution"
102
+ add_plotly_chart_to_slide(slide_4, fig4, Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
103
+
104
+ if figw != None:
105
+ slide_5 = prs.slides.add_slide(prs.slide_layouts[6])
106
+ # title_5 = slide_5.shapes.title
107
+ # title_5.text = "Change in MMM Estimated Prospect Contributions"
108
+ figw.update_layout(
109
+ # title="Distribution Of Spends"
110
+ title={
111
+ 'text': "Change In MMM Estimated Prospect Contribution",
112
+ 'font': {
113
+ 'size': 24,
114
+ 'family': 'Arial',
115
+ 'color': 'black',
116
+ # 'bold': True
117
+ }
118
+ }
119
+
120
+ )
121
+ add_plotly_chart_to_slide(slide_5, figw, Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
122
+ else :
123
+ slide_5 = prs.slides.add_slide(prs.slide_layouts[5])
124
+ title_5 = slide_5.shapes.title
125
+ title_5.text = "Change in MMM Estimated Prospect Contributions"
126
+
127
+ slide_6 = prs.slides.add_slide(prs.slide_layouts[6])
128
+ # title_6 = slide_6.shapes.title
129
+ # title_6.text = "Base Decomposition"
130
+ add_plotly_chart_to_slide(slide_6, fig6, Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
131
+
132
+ slide_7 = prs.slides.add_slide(prs.slide_layouts[6])
133
+ # title_7 = slide_7.shapes.title
134
+ # title_7.text = "Media Decomposition"
135
+ add_plotly_chart_to_slide(slide_7, fig7, Inches(0.25), Inches(0.25), width=Inches(9.25), height=Inches(6.75))
136
+
137
+
138
+
139
+
140
+
141
+
142
+ # prs.save('MMM_Model_Result Overview.pptx')
143
+
144
+ # # print("PowerPoint slides created successfully.")
145
+
146
+ # Save to a BytesIO object
147
+ ppt_stream = BytesIO()
148
+ prs.save(ppt_stream)
149
+ ppt_stream.seek(0)
150
+
151
+ return ppt_stream.getvalue()
152
+
153
+ def get_random_effects(media_data, panel_col, mdf):
154
+ random_eff_df = pd.DataFrame(columns=[panel_col, "random_effect"])
155
+
156
+ for i, market in enumerate(media_data[panel_col].unique()):
157
+ # # # print(i, end='\r')
158
+ intercept = mdf.random_effects[market].values[0]
159
+ random_eff_df.loc[i, 'random_effect'] = intercept
160
+ random_eff_df.loc[i, panel_col] = market
161
+
162
+ return random_eff_df
163
+
164
+
165
+ def process_train_and_test(train, test, features, panel_col, target_col):
166
+ X1 = train[features]
167
+
168
+ ss = MinMaxScaler()
169
+ X1 = pd.DataFrame(ss.fit_transform(X1), columns=X1.columns)
170
+
171
+ X1[panel_col] = train[panel_col]
172
+ X1[target_col] = train[target_col]
173
+
174
+ if test is not None:
175
+ X2 = test[features]
176
+ X2 = pd.DataFrame(ss.transform(X2), columns=X2.columns)
177
+ X2[panel_col] = test[panel_col]
178
+ X2[target_col] = test[target_col]
179
+ return X1, X2
180
+ return X1
181
+
182
+ def mdf_predict(X_df, mdf, random_eff_df) :
183
+ X=X_df.copy()
184
+ X=pd.merge(X, random_eff_df[[panel_col,'random_effect']], on=panel_col, how='left')
185
+ X['pred_fixed_effect'] = mdf.predict(X)
186
+
187
+ X['pred'] = X['pred_fixed_effect'] + X['random_effect']
188
+ X.to_csv('Test/merged_df_contri.csv',index=False)
189
+ X.drop(columns=['pred_fixed_effect', 'random_effect'], inplace=True)
190
+
191
+ return X
192
+
193
+
194
+ target_col='Prospects'
195
+ target='Prospects'
196
+
197
+ # is_panel=False
198
+ # is_panel = st.session_state['is_panel']
199
+ #panel_col = [col.lower().replace('.','_').replace('@','_').replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_") for col in st.session_state['bin_dict']['Panel Level 1'] ] [0]# set the panel column
200
+ panel_col='Panel'
201
+ date_col = 'date'
202
+
203
+ #st.write(media_data)
204
+
205
+ is_panel = True
206
+
207
+ # panel_col='markets'
208
+ date_col = 'date'
209
+ for k, v in st.session_state.items():
210
+
211
+ if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
212
+ st.session_state[k] = v
213
+
214
+ authenticator = st.session_state.get('authenticator')
215
+
216
+ if authenticator is None:
217
+ authenticator = load_authenticator()
218
+
219
+ name, authentication_status, username = authenticator.login('Login', 'main')
220
+ auth_status = st.session_state['authentication_status']
221
+
222
+ if auth_status:
223
+ authenticator.logout('Logout', 'main')
224
+
225
+ is_state_initiaized = st.session_state.get('initialized',False)
226
+ if not is_state_initiaized:
227
+ a=1
228
+
229
+ with st.expander("View Channel Wise Spend And Prospect Analysis "):
230
+ # Create two columns for start date and end date input
231
+ col1, col2 = st.columns(2)
232
+ min_date,max_date = sf.get_date_range()
233
+ # st.write(min_date,max_date)
234
+ # min_date = datetime(2023, 1, 1)
235
+ # max_date = datetime(2024, 12, 31)
236
+ default_date1,default_date2 = sf.get_default_dates()
237
+ # st.write(default_date1,default_date2)
238
+ with col1:
239
+ start_date = st.date_input("Start Date: ",value=default_date1,min_value=min_date,
240
+ max_value=max_date)
241
+ with col2:
242
+ end_date = st.date_input("End Date: ",value = default_date2,min_value=min_date,
243
+ max_value=max_date)
244
+ # col1, col2 = st.columns(2)
245
+ # with col1:
246
+ # fig = sf.pie_spend(start_date,end_date)
247
+ # st.plotly_chart(fig,use_container_width=True)
248
+ # with col2:
249
+ # fig = sf.pie_contributions(start_date,end_date)
250
+ # st.plotly_chart(fig,use_container_width=True)
251
+ # st.header("Distribution of Spends and Contributions")
252
+ fig1 = sf.pie_charts(start_date,end_date)
253
+ st.plotly_chart(fig1,use_container_width=True)
254
+
255
+ ## Channel Contribution Bar Chart
256
+ fig2 =sf.channel_contribution(start_date,end_date)
257
+ st.plotly_chart(fig2,use_container_width=True)
258
+ fig3 = sf.chanel_spends(start_date,end_date)
259
+ st.plotly_chart(fig3,use_container_width=True)
260
+ # Format first three rows in percentage format
261
+ # styled_df = sf.shares_table_func(shares_df)
262
+ # # styled_df = styled_df.round(0).astype(int)
263
+ # styled_df.iloc[:3] = (styled_df.iloc[:3]).astype(int)
264
+
265
+ # # Round next two rows to two decimal places
266
+ # styled_df.iloc[3:5] = styled_df.iloc[3:5].round(0).astype(str)
267
+
268
+ # st.table(styled_df)
269
+ shares_df = sf.shares_df_func(start_date,end_date)
270
+ shares_df1 = sf.shares_table_func(shares_df)
271
+ st.dataframe(sf.shares_table_func(shares_df),use_container_width=True)
272
+ shares_df2 = sf.eff_table_func(shares_df)
273
+ st.dataframe(sf.eff_table_func(shares_df).style.format({"TOTAL SPEND": "{:,.0f}", "TOTAL SUPPORT": "{:,.0f}", "TOTAL CONTRIBUTION": "{:,.0f}"}),use_container_width=True)
274
+
275
+ ### CPP CHART
276
+ fig4 = sf.cpp(start_date,end_date)
277
+ st.plotly_chart(fig4,use_container_width=True)
278
+
279
+ with st.expander("View Change in MMM Estimated Prospect Contributions Analysis"):
280
+ data_selection_type = st.radio("Select Input Type",["Compare Monthly Change", "Compare Custom Range"])
281
+ waterfall_start_date,waterfall_end_date = start_date,end_date
282
+ # Dropdown menu options
283
+ st.markdown("<h1 style='font-size:28px;'>Change in MMM Estimated Prospect Contributions</h1>", unsafe_allow_html=True)
284
+ if data_selection_type == "Compare Monthly Change":
285
+ options = [
286
+ "Month on Month",
287
+ "Year on Year"]
288
+ col1, col2 = st.columns(2)
289
+ # Create a dropdown menu
290
+ with col1:
291
+ selected_option = st.selectbox('Select a comparison', options)
292
+ with col2:
293
+ st.markdown("""</br>""",unsafe_allow_html=True)
294
+ if selected_option == "Month on Month" :
295
+
296
+ st.markdown(
297
+ f"""
298
+ <div style="padding: 5px; border-radius: 5px; background-color: #FFFFE0; width: fit-content; display: inline-block;">
299
+ <strong> Comparision of current month spends to previous month spends</strong>
300
+ </div>
301
+ """,
302
+ unsafe_allow_html=True
303
+ )
304
+ else :
305
+ st.markdown(
306
+ f"""
307
+ <div style="padding: 5px; border-radius: 5px; background-color: #FFFFE0; width: fit-content; display: inline-block;">
308
+ <strong> Comparision of current month spends to the same month in previous year</strong>
309
+ </div>
310
+ """,
311
+ unsafe_allow_html=True
312
+ )
313
+ # Waterfall chart
314
+
315
+ def get_month_year_list(start_date, end_date):
316
+ # Generate a range of dates from start_date to end_date with a monthly frequency
317
+ dates = pd.date_range(start=start_date, end=end_date, freq='MS') # 'MS' is month start frequency
318
+
319
+ # Extract month and year from each date and create a list of tuples
320
+ month_year_list = [(date.month, date.year) for date in dates]
321
+
322
+ return month_year_list
323
+ def get_start_end_dates(month, year):
324
+ start_date = datetime(year, month, 1).date()
325
+
326
+ if month == 12:
327
+ end_date = datetime(year + 1, 1, 1).date() - timedelta(days=1)
328
+ else:
329
+ end_date = datetime(year, month + 1, 1).date() - timedelta(days=1)
330
+
331
+ return start_date, end_date
332
+
333
+ month_year_list = get_month_year_list(start_date, end_date)
334
+ dropdown_options = [f"{date.strftime('%B %Y')}" for date in pd.date_range(start=start_date, end=end_date, freq='MS')]
335
+ waterfall_option = st.selectbox("Select a month:", dropdown_options)
336
+ waterfall_date = datetime.strptime(waterfall_option, "%B %Y")
337
+ waterfall_month = waterfall_date.month
338
+ waterfall_year = waterfall_date.year
339
+ waterfall_start_date, waterfall_end_date = get_start_end_dates(waterfall_month, waterfall_year)
340
+ # st.write("abc")
341
+ # figw = sf.waterfall(waterfall_start_date,waterfall_end_date)
342
+ figw= sf.waterfall(waterfall_start_date,waterfall_end_date,selected_option)
343
+ st.plotly_chart(figw,use_container_width=True)
344
+
345
+ elif data_selection_type == "Compare Custom Range":
346
+ col1, col2 = st.columns(2)
347
+ min_date,max_date = sf.get_date_range()
348
+ with col1:
349
+ st.write("Select Time Period 1")
350
+ sc1,sc2 = st.columns(2)
351
+ with sc1:
352
+ waterfall_start_date1 = st.date_input("Start Date 1: ",value=start_date,min_value=min_date,
353
+ max_value=max_date)
354
+ with sc2:
355
+ waterfall_end_date1 = st.date_input("End Date 1: ",value = end_date,min_value=min_date,
356
+ max_value=max_date)
357
+ with col2:
358
+ st.write("Select Time Period 2")
359
+ ec1,ec2 = st.columns(2)
360
+ with ec1:
361
+ waterfall_start_date2 = st.date_input("Start Date 2: ",value=end_date-timedelta(days = -1),min_value=min_date,
362
+ max_value=max_date)
363
+ with ec2:
364
+ diff = min((start_date-end_date).days,-30)
365
+ waterfall_end_date2 = st.date_input("End Date 2: ",value = start_date,min_value=min_date,
366
+ max_value=max_date)
367
+ try:
368
+ figw= sf.waterfall2(waterfall_start_date1,waterfall_end_date1,waterfall_start_date2,waterfall_end_date2)
369
+ st.plotly_chart(figw,use_container_width=True)
370
+ except:
371
+ st.warning("Previous data does not exist")
372
+
373
+
374
+
375
+ # Waterfall table
376
+ # shares_df = sf.shares_df_func(waterfall_start_date,waterfall_end_date)
377
+ st.table(sf.waterfall_table_func(shares_df).style.format("{:.0%}"))
378
+
379
+
380
+ with st.expander("View Decomposition Analysis"):
381
+ ### Base decomp CHART
382
+ fig6 = sf.base_decomp()
383
+ st.plotly_chart(fig6,use_container_width=True)
384
+
385
+ ### Media decomp CHART
386
+ fig7 = sf.media_decomp()
387
+ st.plotly_chart(fig7,use_container_width=True)
388
+
389
+ if st.button("Prepare Download Of Analysis"):
390
+ ppt_file = save_ppt_file(fig1,fig2,fig3,fig4,fig6,fig7,figw,start_date,end_date,shares_df1,shares_df2)
391
+ # Add a download button
392
+ st.download_button(
393
+ label="Download Analysis",
394
+ data=ppt_file,
395
+ file_name="MMM_Model_Result Overview.pptx",
396
+ mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
397
+ )
398
+
Overview_data_test.xlsx ADDED
Binary file (27.4 kB). View file
 
Overview_data_test_panel@#prospects.xlsx ADDED
Binary file (78.6 kB). View file
 
README.md CHANGED
@@ -1,12 +1,12 @@
1
- ---
2
- title: BAT MMO
3
- emoji: 🔥
4
- colorFrom: pink
5
- colorTo: yellow
6
- sdk: streamlit
7
- sdk_version: 1.41.1
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ ---
2
+ title: UOPX
3
+ emoji: 🏆
4
+ colorFrom: indigo
5
+ colorTo: pink
6
+ sdk: streamlit
7
+ sdk_version: 1.32.1
8
+ app_file: Model_Result_Overview.py
9
+ pinned: false
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
Scenario.py ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ import numpy as np
6
+ import plotly.express as px
7
+ import plotly.graph_objects as go
8
+ import pandas as pd
9
+ import seaborn as sns
10
+ import matplotlib.pyplot as plt
11
+ import datetime
12
+ from utilities import set_header,initialize_data,load_local_css
13
+ from scipy.optimize import curve_fit
14
+ import statsmodels.api as sm
15
+ from plotly.subplots import make_subplots
16
+
17
+ st.set_page_config(
18
+ page_title="Data Validation",
19
+ page_icon=":shark:",
20
+ layout="wide",
21
+ initial_sidebar_state='collapsed'
22
+ )
23
+ load_local_css('styles.css')
24
+ set_header()
25
+
26
+ def format_numbers(x):
27
+ if abs(x) >= 1e6:
28
+ # Format as millions with one decimal place and commas
29
+ return f'{x/1e6:,.1f}M'
30
+ elif abs(x) >= 1e3:
31
+ # Format as thousands with one decimal place and commas
32
+ return f'{x/1e3:,.1f}K'
33
+ else:
34
+ # Format with one decimal place and commas for values less than 1000
35
+ return f'{x:,.1f}'
36
+
37
+ def format_axis(x):
38
+ if isinstance(x, tuple):
39
+ x = x[0] # Extract the numeric value from the tuple
40
+ if abs(x) >= 1e6:
41
+ return f'{x / 1e6:.0f}M'
42
+ elif abs(x) >= 1e3:
43
+ return f'{x / 1e3:.0f}k'
44
+ else:
45
+ return f'{x:.0f}'
46
+
47
+
48
+ attributred_app_installs=pd.read_csv("attributed_app_installs.csv")
49
+ attributred_app_installs_tactic=pd.read_excel('attributed_app_installs_tactic.xlsx')
50
+ data=pd.read_excel('Channel_wise_imp_click_spends.xlsx')
51
+ data['Date']=pd.to_datetime(data['Date'])
52
+ st.header('Saturation Curves')
53
+
54
+ # st.dataframe(data.head(2))
55
+ st.markdown('Data QC')
56
+
57
+ st.markdown('Channel wise summary')
58
+ summary_df=data.groupby(data['Date'].dt.strftime('%B %Y')).sum()
59
+ summary_df=summary_df.sort_index(key=lambda x: pd.to_datetime(x, format='%B %Y'))
60
+ st.dataframe(summary_df.applymap(format_numbers))
61
+
62
+
63
+
64
+ def line_plot_target(df,target,title):
65
+ df=df
66
+ df['Date_unix'] = df['Date'].apply(lambda x: x.timestamp())
67
+
68
+ # Perform polynomial fitting
69
+ coefficients = np.polyfit(df['Date_unix'], df[target], 1)
70
+ # st.dataframe(df)
71
+ coefficients = np.polyfit(df['Date'].view('int64'), df[target], 1)
72
+ trendline = np.poly1d(coefficients)
73
+ fig = go.Figure()
74
+
75
+ fig.add_trace(go.Scatter(x=df['Date'], y=df[target], mode='lines', name=target,line=dict(color='#11B6BD')))
76
+ trendline_x = df['Date']
77
+ trendline_y = trendline(df['Date'].view('int64'))
78
+
79
+
80
+ fig.add_trace(go.Scatter(x=trendline_x, y=trendline_y, mode='lines', name='Trendline', line=dict(color='#739FAE')))
81
+
82
+ fig.update_layout(
83
+ title=title,
84
+ xaxis=dict(type='date')
85
+ )
86
+
87
+ for year in df['Date'].dt.year.unique()[1:]:
88
+
89
+ january_1 = pd.Timestamp(year=year, month=1, day=1)
90
+ fig.add_shape(
91
+ go.layout.Shape(
92
+ type="line",
93
+ x0=january_1,
94
+ x1=january_1,
95
+ y0=0,
96
+ y1=1,
97
+ xref="x",
98
+ yref="paper",
99
+ line=dict(color="grey", width=1.5, dash="dash"),
100
+ )
101
+ )
102
+
103
+ return fig
104
+ channels_d= data.columns[:28]
105
+ channels=list(set([col.replace('_impressions','').replace('_clicks','').replace('_spend','') for col in channels_d if col.lower()!='date']))
106
+ channel= st.selectbox('Select Channel_name',channels)
107
+ target_column = st.selectbox('Select Channel)',[col for col in data.columns if col.startswith(channel)])
108
+ fig=line_plot_target(data, target=str(target_column), title=f'{str(target_column)} Over Time')
109
+ st.plotly_chart(fig, use_container_width=True)
110
+
111
+ # st.markdown('## Saturation Curve')
112
+
113
+
114
+ st.header('Build saturation curve')
115
+
116
+ # Your data
117
+ # st.write(len(attributred_app_installs))
118
+ # st.write(len(data))
119
+ # col=st.columns(3)
120
+ # with col[0]:
121
+ col=st.columns(2)
122
+ with col[0]:
123
+ if st.checkbox('Cap Outliers'):
124
+ x = data[target_column]
125
+ x.index=data['Date']
126
+ # st.write(x)
127
+ result = sm.tsa.seasonal_decompose(x, model='additive')
128
+ x_resid=result.resid
129
+ # fig = make_subplots(rows=1, cols=1, shared_xaxes=True, vertical_spacing=0.02)
130
+ # trace_x = go.Scatter(x=data['Date'], y=x, mode='lines', name='x')
131
+ # fig.add_trace(trace_x)
132
+ # trace_x_resid = go.Scatter(x=data['Date'], y=x_resid, mode='lines', name='x_resid', yaxis='y2',line=dict(color='orange'))
133
+
134
+ # fig.add_trace(trace_x_resid)
135
+ # fig.update_layout(title='',
136
+ # xaxis=dict(title='Date'),
137
+ # yaxis=dict(title='x', side='left'),
138
+ # yaxis2=dict(title='x_resid', side='right'))
139
+ # st.title('')
140
+ # st.plotly_chart(fig)
141
+
142
+ # x=result.resid
143
+ # x=x.fillna(0)
144
+ x_mean = np.mean(x)
145
+ x_std = np.std(x)
146
+ x_scaled = (x - x_mean) / x_std
147
+ lower_threshold = -2.0
148
+ upper_threshold = 2.0
149
+ x_scaled = np.clip(x_scaled, lower_threshold, upper_threshold)
150
+ else:
151
+ x = data[target_column]
152
+ x_mean = np.mean(x)
153
+ x_std = np.std(x)
154
+ x_scaled = (x - x_mean) / x_std
155
+ with col[1]:
156
+ if st.checkbox('Attributed'):
157
+ column=[col for col in attributred_app_installs.columns if col in target_column]
158
+ data['app_installs_appsflyer']=attributred_app_installs[column]
159
+ y=data['app_installs_appsflyer']
160
+ title='Attributed-App_installs_appsflyer'
161
+ # st.dataframe(y)
162
+ # st.dataframe(x)
163
+ # st.dataframe(x_scaled)
164
+ else:
165
+ y=data["app_installs_appsflyer"]
166
+ title='App_installs_appsflyer'
167
+ # st.write(len(y))
168
+ # Curve fitting function
169
+ def sigmoid(x, K, a, x0):
170
+ return K / (1 + np.exp(-a * (x - x0)))
171
+
172
+ initial_K = np.max(y)
173
+ initial_a = 1
174
+ initial_x0 = 0
175
+ columns=st.columns(3)
176
+
177
+
178
+ with columns[0]:
179
+ K = st.number_input('K (Amplitude)', min_value=0.01, max_value=2.0 * np.max(y), value=float(initial_K), step=5.0)
180
+ with columns[1]:
181
+ a = st.number_input('a (Slope)', min_value=0.01, max_value=5.0, value=float(initial_a), step=0.5)
182
+ with columns[2]:
183
+ x0 = st.number_input('x0 (Center)', min_value=float(min(x_scaled)), max_value=float(max(x_scaled)), value=float(initial_x0), step=2.0)
184
+ params, _ = curve_fit(sigmoid, x_scaled, y, p0=[K, a, x0], maxfev=20000)
185
+
186
+
187
+ x_slider = st.slider('X Value', min_value=float(min(x)), max_value=float(max(x))+1, value=float(x_mean), step=1.)
188
+
189
+ # Calculate the corresponding value on the fitted curve
190
+ x_slider_scaled = (x_slider - x_mean) / x_std
191
+ y_slider_fit = sigmoid(x_slider_scaled, *params)
192
+
193
+ # Display the corresponding value
194
+ st.write(f'{target_column}: {format_numbers(x_slider)}')
195
+ st.write(f'Corresponding App_installs: {format_numbers(y_slider_fit)}')
196
+
197
+ # Scatter plot of your data
198
+ fig = px.scatter(data_frame=data, x=x_scaled, y=y, labels={'x': f'{target_column}', 'y': 'App Installs'}, title=title)
199
+
200
+ # Add the fitted sigmoid curve to the plot
201
+ x_fit = np.linspace(min(x_scaled), max(x_scaled), 100) # Generate x values for the curve
202
+ y_fit = sigmoid(x_fit, *params)
203
+ fig.add_trace(px.line(x=x_fit, y=y_fit).data[0])
204
+ fig.data[1].update(line=dict(color='orange'))
205
+ fig.add_vline(x=x_slider_scaled, line_dash='dash', line_color='red', annotation_text=f'{format_numbers(x_slider)}')
206
+
207
+ x_tick_labels = {format_axis(x_scaled[i]): format_axis(x[i]) for i in range(len(x_scaled))}
208
+ num_points = 30 # Number of points you want to select
209
+ keys = list(x_tick_labels.keys())
210
+ values = list(x_tick_labels.values())
211
+ spacing = len(keys) // num_points # Calculate the spacing
212
+ if spacing==0:
213
+ spacing=15
214
+ selected_keys = keys[::spacing]
215
+ selected_values = values[::spacing]
216
+ else:
217
+ selected_keys = keys[::spacing]
218
+ selected_values = values[::spacing]
219
+
220
+ # Update the x-axis ticks with the selected keys and values
221
+ fig.update_xaxes(tickvals=selected_keys, ticktext=selected_values)
222
+ fig.update_xaxes(tickvals=list(x_tick_labels.keys()), ticktext=list(x_tick_labels.values()))
223
+ # Show the plot using st.plotly_chart
224
+
225
+ fig.update_xaxes(showgrid=False)
226
+ fig.update_yaxes(showgrid=False)
227
+ fig.update_layout(
228
+ width=600, # Adjust the width as needed
229
+ height=600 # Adjust the height as needed
230
+ )
231
+ st.plotly_chart(fig)
232
+
233
+
234
+
235
+
236
+ st.markdown('Tactic level')
237
+ if channel=='paid_social':
238
+
239
+ tactic_data=pd.read_excel("Tatcic_paid.xlsx",sheet_name='paid_social_impressions')
240
+ else:
241
+ tactic_data=pd.read_excel("Tatcic_paid.xlsx",sheet_name='digital_app_display_impressions')
242
+ target_column = st.selectbox('Select Channel)',[col for col in tactic_data.columns if col!='Date' and col!='app_installs_appsflyer'])
243
+ fig=line_plot_target(tactic_data, target=str(target_column), title=f'{str(target_column)} Over Time')
244
+ st.plotly_chart(fig, use_container_width=True)
245
+
246
+ if st.checkbox('Cap Outliers',key='tactic1'):
247
+ x = tactic_data[target_column]
248
+ x_mean = np.mean(x)
249
+ x_std = np.std(x)
250
+ x_scaled = (x - x_mean) / x_std
251
+ lower_threshold = -2.0
252
+ upper_threshold = 2.0
253
+ x_scaled = np.clip(x_scaled, lower_threshold, upper_threshold)
254
+ else:
255
+ x = tactic_data[target_column]
256
+ x_mean = np.mean(x)
257
+ x_std = np.std(x)
258
+ x_scaled = (x - x_mean) / x_std
259
+
260
+ if st.checkbox('Attributed',key='tactic2'):
261
+ column=[col for col in attributred_app_installs_tactic.columns if col in target_column]
262
+ tactic_data['app_installs_appsflyer']=attributred_app_installs_tactic[column]
263
+ y=tactic_data['app_installs_appsflyer']
264
+ title='Attributed-App_installs_appsflyer'
265
+ # st.dataframe(y)
266
+ # st.dataframe(x)
267
+ # st.dataframe(x_scaled)
268
+ else:
269
+ y=data["app_installs_appsflyer"]
270
+ title='App_installs_appsflyer'
271
+ # st.write(len(y))
272
+ # Curve fitting function
273
+ def sigmoid(x, K, a, x0):
274
+ return K / (1 + np.exp(-a * (x - x0)))
275
+
276
+ # Curve fitting
277
+ # st.dataframe(x_scaled.head(3))
278
+ # # y=y.astype(float)
279
+ # st.dataframe(y.head(3))
280
+ initial_K = np.max(y)
281
+ initial_a = 1
282
+ initial_x0 = 0
283
+ K = st.number_input('K (Amplitude)', min_value=0.01, max_value=2.0 * np.max(y), value=float(initial_K), step=5.0,key='tactic3')
284
+ a = st.number_input('a (Slope)', min_value=0.01, max_value=5.0, value=float(initial_a), step=2.0,key='tactic41')
285
+ x0 = st.number_input('x0 (Center)', min_value=float(min(x_scaled)), max_value=float(max(x_scaled)), value=float(initial_x0), step=2.0,key='tactic4')
286
+ params, _ = curve_fit(sigmoid, x_scaled, y, p0=[K, a, x0], maxfev=20000)
287
+
288
+ # Slider to vary x
289
+ x_slider = st.slider('X Value', min_value=float(min(x)), max_value=float(max(x)), value=float(x_mean), step=1.,key='tactic7')
290
+
291
+ # Calculate the corresponding value on the fitted curve
292
+ x_slider_scaled = (x_slider - x_mean) / x_std
293
+ y_slider_fit = sigmoid(x_slider_scaled, *params)
294
+
295
+ # Display the corresponding value
296
+ st.write(f'{target_column}: {format_axis(x_slider)}')
297
+ st.write(f'Corresponding App_installs: {format_axis(y_slider_fit)}')
298
+
299
+ # Scatter plot of your data
300
+ fig = px.scatter(data_frame=data, x=x_scaled, y=y, labels={'x': f'{target_column}', 'y': 'App Installs'}, title=title)
301
+
302
+ # Add the fitted sigmoid curve to the plot
303
+ x_fit = np.linspace(min(x_scaled), max(x_scaled), 100) # Generate x values for the curve
304
+ y_fit = sigmoid(x_fit, *params)
305
+ fig.add_trace(px.line(x=x_fit, y=y_fit).data[0])
306
+ fig.data[1].update(line=dict(color='orange'))
307
+ fig.add_vline(x=x_slider_scaled, line_dash='dash', line_color='red', annotation_text=f'{format_numbers(x_slider)}')
308
+
309
+
310
+
311
+ x_tick_labels = {format_axis((x_scaled[i],0)): format_axis(x[i]) for i in range(len(x_scaled))}
312
+ num_points = 50 # Number of points you want to select
313
+ keys = list(x_tick_labels.keys())
314
+ values = list(x_tick_labels.values())
315
+ spacing = len(keys) // num_points # Calculate the spacing
316
+ if spacing==0:
317
+ spacing=2
318
+ selected_keys = keys[::spacing]
319
+ selected_values = values[::spacing]
320
+ else:
321
+ selected_keys = keys[::spacing]
322
+ selected_values = values[::spacing]
323
+
324
+ # Update the x-axis ticks with the selected keys and values
325
+ fig.update_xaxes(tickvals=selected_keys, ticktext=selected_values)
326
+
327
+ # Round the x-axis and y-axis tick values to zero decimal places
328
+ fig.update_xaxes(tickformat=".f") # Format x-axis ticks to zero decimal places
329
+ fig.update_yaxes(tickformat=".f") # Format y-axis ticks to zero decimal places
330
+
331
+ # Show the plot using st.plotly_chart
332
+ fig.update_xaxes(showgrid=False)
333
+ fig.update_yaxes(showgrid=False)
334
+ fig.update_layout(
335
+ width=600, # Adjust the width as needed
336
+ height=600 # Adjust the height as needed
337
+ )
338
+ st.plotly_chart(fig)
Streamlit_functions.py ADDED
@@ -0,0 +1,1659 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ from scipy.optimize import curve_fit
5
+ from sklearn.preprocessing import MinMaxScaler
6
+ import warnings
7
+ import warnings
8
+ warnings.filterwarnings("ignore")
9
+ import os
10
+ import plotly.graph_objects as go
11
+ from datetime import datetime,timedelta
12
+ from plotly.subplots import make_subplots
13
+ import pandas as pd
14
+ import json
15
+ from numerize.numerize import numerize
16
+
17
+ # working_directory = r"C:\Users\PragyaJatav\Downloads\Deliverables\Deliverables\Response Curves 09_07_24\Response Curves Resources"
18
+ # os.chdir(working_directory)
19
+
20
+ ## reading input data
21
+ df= pd.read_csv('response_curves_input_file.csv')
22
+ df.dropna(inplace=True)
23
+ df['Date'] = pd.to_datetime(df['Date'])
24
+ df.reset_index(inplace=True)
25
+ # df
26
+
27
+ spend_cols = ['tv_broadcast_spend',
28
+ 'tv_cable_spend',
29
+ 'stream_video_spend',
30
+ 'olv_spend',
31
+ 'disp_prospect_spend',
32
+ 'disp_retarget_spend',
33
+ 'social_prospect_spend',
34
+ 'social_retarget_spend',
35
+ 'search_brand_spend',
36
+ 'search_nonbrand_spend',
37
+ 'cm_spend',
38
+ 'audio_spend',
39
+ 'email_spend']
40
+ spend_cols2 = ['tv_broadcast_spend',
41
+ 'tv_cable_spend',
42
+ 'stream_video_spend',
43
+ 'olv_spend',
44
+ 'disp_prospect_spend',
45
+ 'disp_retarget_spend',
46
+ 'social_prospect_spend',
47
+ 'social_retarget_spend',
48
+ 'search_brand_spend',
49
+ 'search_nonbrand_spend',
50
+ 'cm_spend',
51
+ 'audio_spend',
52
+ 'email_spend', 'Date']
53
+ metric_cols = ['tv_broadcast_grp',
54
+ 'tv_cable_grp',
55
+ 'stream_video_imp',
56
+ 'olv_imp',
57
+ 'disp_prospect_imp',
58
+ 'disp_retarget_imp',
59
+ 'social_prospect_imp',
60
+ 'social_retarget_imp',
61
+ 'search_brand_imp',
62
+ 'search_nonbrand_imp',
63
+ 'cm_spend',
64
+ 'audio_imp',
65
+ 'email_imp']
66
+ channels = [
67
+ 'BROADCAST TV',
68
+ 'CABLE TV',
69
+ 'CONNECTED & OTT TV',
70
+ 'VIDEO',
71
+ 'DISPLAY PROSPECTING',
72
+ 'DISPLAY RETARGETING',
73
+ 'SOCIAL PROSPECTING',
74
+ 'SOCIAL RETARGETING',
75
+ 'SEARCH BRAND',
76
+ 'SEARCH NON-BRAND',
77
+ 'DIGITAL PARTNERS',
78
+ 'AUDIO',
79
+ 'EMAIL']
80
+ channels2 = [
81
+ 'BROADCAST TV',
82
+ 'CABLE TV',
83
+ 'CONNECTED & OTT TV',
84
+ 'VIDEO',
85
+ 'DISPLAY PROSPECTING',
86
+ 'DISPLAY RETARGETING',
87
+ 'SOCIAL PROSPECTING',
88
+ 'SOCIAL RETARGETING',
89
+ 'SEARCH BRAND',
90
+ 'SEARCH NON-BRAND',
91
+ 'DIGITAL PARTNERS',
92
+ 'AUDIO',
93
+ 'EMAIL','Date']
94
+ contribution_cols = [
95
+ 'Broadcast TV_Prospects',
96
+ 'Cable TV_Prospects',
97
+ 'Connected & OTT TV_Prospects',
98
+ 'Video_Prospects',
99
+ 'Display Prospecting_Prospects',
100
+ 'Display Retargeting_Prospects',
101
+ 'Social Prospecting_Prospects',
102
+ 'Social Retargeting_Prospects',
103
+ 'Search Brand_Prospects',
104
+ 'Search Non-brand_Prospects',
105
+ 'Digital Partners_Prospects',
106
+ 'Audio_Prospects',
107
+ 'Email_Prospects']
108
+
109
+ def get_date_range():
110
+ return df['Date'].min(),df['Date'].max()+ timedelta(days=7)
111
+
112
+ def get_default_dates():
113
+ return df['Date'].max()- timedelta(days=21),df['Date'].max()+ timedelta(days=6)
114
+
115
+
116
+ def pie_charts(start_date,end_date):
117
+ start_date = pd.to_datetime(start_date)
118
+ end_date = pd.to_datetime(end_date)
119
+ import plotly.graph_objects as go
120
+ from plotly.subplots import make_subplots
121
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
122
+ data1 = pd.DataFrame(cur_data[spend_cols].sum().transpose())
123
+ data2 = pd.DataFrame(cur_data[contribution_cols].sum().transpose())
124
+
125
+ data1.index = channels
126
+ data1.columns = ["p"]
127
+
128
+ data2.index = channels
129
+ data2.columns = ["p"]
130
+
131
+ colors = ['#ff2b2b', # Pastel Peach
132
+ '#0068c9', # Pastel Blue
133
+ '#83c9ff', # Pastel Pink
134
+
135
+ '#ffabab', # Pastel Purple
136
+ '#29b09d', # Pastel Green
137
+ '#7defa1', # Pastel Yellow
138
+ '#ff8700', # Pastel Gray
139
+ '#ffd16a', # Pastel Red
140
+ '#6d3fc0', # Pastel Rose
141
+ '#d5dae5', # Pastel Lavender
142
+ '#309bff', # Pastel Mauve
143
+ '#e9f5ff', # Pastel Beige
144
+ '#BEBADA' # Pastel Lilac
145
+ ]
146
+
147
+
148
+
149
+ fig = make_subplots(rows=1, cols=2, specs=[[{'type':'domain'}, {'type':'domain'}]])
150
+
151
+ fig.add_trace(go.Pie(labels=channels,
152
+ values=data1["p"],
153
+ name="t2",
154
+ hoverinfo='label+percent',
155
+ textinfo= 'label+percent',
156
+ showlegend= False,textfont=dict(size =10),
157
+ title="Distribution of Spends"
158
+ , marker=dict(colors=colors)
159
+ ), 1, 1)
160
+
161
+ fig.add_trace(go.Pie(labels=channels,
162
+ values=data2["p"],
163
+ name="t2",
164
+ hoverinfo='label+percent',
165
+ textinfo= 'label+percent',
166
+ showlegend= False,
167
+ textfont=dict(size = 10),
168
+ title = "Distribution of Prospect Contributions", marker=dict(colors=colors)
169
+ ), 1, 2)
170
+ # fig.update_layout(
171
+ # title="Distribution Of Spends And Prospect Contributions"
172
+ # )
173
+
174
+ fig.update_layout(
175
+ # title="Distribution Of Spends"
176
+ title={
177
+ 'text': "Distribution Of Spends And Prospects",
178
+ 'font': {
179
+ 'size': 24,
180
+ 'family': 'Arial',
181
+ 'color': 'black',
182
+ # 'bold': True
183
+ }
184
+ }
185
+
186
+ )
187
+
188
+ fig.add_annotation(
189
+ text=f"{start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}",
190
+ x=0,
191
+ y=1.15,
192
+ xref="x domain",
193
+ yref="y domain",
194
+ showarrow=False,
195
+ font=dict(size=18),
196
+ # align='left'
197
+ )
198
+
199
+ return fig
200
+
201
+ def pie_spend(start_date,end_date):
202
+ colors = ['#ff2b2b', # Pastel Peach
203
+ '#0068c9', # Pastel Blue
204
+ '#83c9ff', # Pastel Pink
205
+
206
+ '#ffabab', # Pastel Purple
207
+ '#29b09d', # Pastel Green
208
+ '#7defa1', # Pastel Yellow
209
+ '#ff8700', # Pastel Gray
210
+ '#ffd16a', # Pastel Red
211
+ '#6d3fc0', # Pastel Rose
212
+ '#d5dae5', # Pastel Lavender
213
+ '#309bff', # Pastel Mauve
214
+ '#e9f5ff', # Pastel Beige
215
+ '#BEBADA' # Pastel Lilac
216
+ ]
217
+
218
+ start_date = pd.to_datetime(start_date)
219
+ end_date = pd.to_datetime(end_date)
220
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
221
+ data = pd.DataFrame(cur_data[spend_cols].sum().transpose())
222
+ data.index = channels
223
+ data.columns = ["p"]
224
+ # Create a pie chart with custom options
225
+ fig = go.Figure(data=[go.Pie(
226
+ labels=channels,
227
+ values=data["p"],#ype(str)+'<br>'+data.index,
228
+ hoverinfo='label+percent',
229
+ textinfo= 'label+percent',
230
+ showlegend= False,
231
+ textfont=dict(size = 10)
232
+ , marker=dict(colors=colors)
233
+ )])
234
+
235
+ # Customize the layout
236
+ fig.update_layout(
237
+ # title="Distribution Of Spends"
238
+ title={
239
+ 'text': "Distribution Of Spends",
240
+ 'font': {
241
+ 'size': 24,
242
+ 'family': 'Arial',
243
+ 'color': 'black',
244
+ # 'bold': True
245
+ }
246
+ }
247
+
248
+ )
249
+
250
+ fig.add_annotation(
251
+ text=f"{start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}",
252
+ x=0,
253
+ y=1.15,
254
+ xref="x domain",
255
+ yref="y domain",
256
+ showarrow=False,
257
+ font=dict(size=18),
258
+ # align='left'
259
+ )
260
+
261
+ # Show the figure
262
+ return fig
263
+ def pie_contributions(start_date,end_date):
264
+ colors = ['#ff2b2b', # Pastel Peach
265
+ '#0068c9', # Pastel Blue
266
+ '#83c9ff', # Pastel Pink
267
+
268
+ '#ffabab', # Pastel Purple
269
+ '#29b09d', # Pastel Green
270
+ '#7defa1', # Pastel Yellow
271
+ '#ff8700', # Pastel Gray
272
+ '#ffd16a', # Pastel Red
273
+ '#6d3fc0', # Pastel Rose
274
+ '#d5dae5', # Pastel Lavender
275
+ '#309bff', # Pastel Mauve
276
+ '#e9f5ff', # Pastel Beige
277
+ '#BEBADA' # Pastel Lilac
278
+ ]
279
+ start_date = pd.to_datetime(start_date)
280
+ end_date = pd.to_datetime(end_date)
281
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
282
+ data = pd.DataFrame(cur_data[contribution_cols].sum().transpose())
283
+ data.index = channels
284
+ data.columns = ["p"]
285
+ # Create a pie chart with custom options
286
+ fig = go.Figure(data=[go.Pie(
287
+ labels=channels,
288
+ values=data["p"],#ype(str)+'<br>'+data.index,
289
+ hoverinfo='label+percent',
290
+ textinfo= 'label+percent',
291
+ textposition='auto',
292
+ showlegend= False,
293
+ textfont=dict(size = 10)
294
+ , marker=dict(colors=colors)
295
+ )])
296
+
297
+ # fig.add_annotation(showarrow=False)
298
+ # Customize the layout
299
+ fig.update_layout(
300
+ # title="Distribution Of Contributions",
301
+ title={
302
+ 'text': "Distribution of Prospects",
303
+ 'font': {
304
+ 'size': 24,
305
+ 'family': 'Arial',
306
+ 'color': 'black',
307
+ # 'bold': True
308
+ }
309
+ }
310
+ # margin=dict(t=0, b=0, l=0, r=0)
311
+ )
312
+
313
+ fig.add_annotation(
314
+ text=f"{start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}",
315
+ x=0,
316
+ y=1.15,
317
+ xref="x domain",
318
+ yref="y domain",
319
+ showarrow=False,
320
+ font=dict(size=18),
321
+ # align='left'
322
+ )
323
+
324
+ # Show the figure
325
+ return fig
326
+ def waterfall2(start_date1,end_date1,start_date2,end_date2):
327
+ btn_chart = "Month on Month"
328
+ # if pd.isnull(start_date) == True :
329
+ # start_date = datetime(2024, 1, 28)
330
+ # if pd.isnull(end_date) == True :
331
+ # end_date = datetime(2024, 2, 24)
332
+ # start_date = datetime.strptime(start_date, "%Y-%m-%d")
333
+ # end_date = datetime.strptime(end_date, "%Y-%m-%d")
334
+ # start_date = start_date.datetime.data
335
+ # end_date = end_date.datetime.data
336
+ start_date1 = pd.to_datetime(start_date1)
337
+ end_date1 = pd.to_datetime(end_date1)
338
+ start_date2 = pd.to_datetime(start_date2)
339
+ end_date2 = pd.to_datetime(end_date2)
340
+
341
+ # if btn_chart == "Month on Month":
342
+ # start_date_prev = start_date +timedelta(weeks=-4)
343
+ # end_date_prev = start_date +timedelta(days=-1)
344
+ # else:
345
+ # start_date_prev = start_date +timedelta(weeks=-52)
346
+ # end_date_prev = start_date_prev +timedelta(weeks=4) +timedelta(days=-1)
347
+
348
+
349
+ if start_date1 < df['Date'].min() :
350
+ return "a"
351
+
352
+ cur_data = df[(df['Date'] >= start_date2) & (df['Date'] <= end_date2)]
353
+ prev_data = df[(df['Date'] >= start_date1) & (df['Date'] <= end_date1)]
354
+
355
+
356
+ # Example data for the waterfall chart
357
+ data = [
358
+ {'label': 'Previous Period', 'value': round(prev_data[contribution_cols].values.sum())},
359
+ {'label': 'Broadcast TV', 'value': round(cur_data['Broadcast TV_Prospects'].sum()-prev_data['Broadcast TV_Prospects'].sum())},
360
+ {'label': 'Cable TV', 'value': round(cur_data['Cable TV_Prospects'].sum()-prev_data['Cable TV_Prospects'].sum())},
361
+ {'label': 'Connected & OTT TV', 'value': round(cur_data['Connected & OTT TV_Prospects'].sum()-prev_data['Connected & OTT TV_Prospects'].sum())},
362
+ {'label': 'Video', 'value': round(cur_data['Video_Prospects'].sum()-prev_data['Video_Prospects'].sum())},
363
+ {'label': 'Display Prospecting', 'value': round(cur_data['Display Prospecting_Prospects'].sum()-prev_data['Display Prospecting_Prospects'].sum())},
364
+ {'label': 'Display Retargeting', 'value': round(cur_data['Display Retargeting_Prospects'].sum()-prev_data['Display Retargeting_Prospects'].sum())},
365
+ {'label': 'Social Prospecting', 'value': round(cur_data['Social Prospecting_Prospects'].sum()-prev_data['Social Prospecting_Prospects'].sum())},
366
+ {'label': 'Social Retargeting', 'value': round(cur_data['Social Retargeting_Prospects'].sum()-prev_data['Social Retargeting_Prospects'].sum())},
367
+ {'label': 'Search Brand', 'value': round(cur_data['Search Brand_Prospects'].sum()-prev_data['Search Brand_Prospects'].sum())},
368
+ {'label': 'Search Non-brand', 'value': round(cur_data['Search Non-brand_Prospects'].sum()-prev_data['Search Non-brand_Prospects'].sum())},
369
+ {'label': 'Digital Partners', 'value': round(cur_data['Digital Partners_Prospects'].sum()-prev_data['Digital Partners_Prospects'].sum())},
370
+ {'label': 'Audio', 'value': round(cur_data['Audio_Prospects'].sum()-prev_data['Audio_Prospects'].sum())},
371
+ {'label': 'Email', 'value': round(cur_data['Email_Prospects'].sum()-prev_data['Email_Prospects'].sum())},
372
+ {'label': 'Current Period', 'value': round(cur_data[contribution_cols].values.sum())}
373
+ ]
374
+
375
+ # Calculate cumulative values for the waterfall chart
376
+ cumulative = [0]
377
+ for i in range(len(data)):
378
+ cumulative.append(cumulative[-1] + data[i]['value'])
379
+
380
+ # Adjusting values to start from zero for both first and last columns
381
+ cumulative[-1] = 0 # Set the last cumulative value to zero
382
+
383
+ # Extracting labels and values
384
+ labels = [item['label'] for item in data]
385
+ values = [item['value'] for item in data]
386
+
387
+ # Plotting the waterfall chart using go.Bar
388
+ bars = []
389
+ for i in range(len(data)):
390
+ color = '#4A88D9' if i == 0 or i == len(data) - 1 else '#DC5537' # Blue for first and last, gray for others
391
+ hover_text = f"<b>{labels[i]}</b><br>Value: {abs(values[i])}"
392
+
393
+ bars.append(go.Bar(
394
+ x=[labels[i]],
395
+ y=[cumulative[i+1] - cumulative[i]],
396
+ base=[cumulative[i]],
397
+ text=[f"{abs(values[i]):,}"],
398
+ textposition='auto',
399
+ hovertemplate=hover_text,
400
+ marker=dict(color=color),
401
+ showlegend=False
402
+ ))
403
+
404
+ # Creating the figure
405
+ fig = go.Figure(data=bars)
406
+
407
+ # Updating layout for black background and gray gridlines
408
+ if btn_chart == "Month on Month":
409
+ fig.update_layout(
410
+ title=f"Change In MMM Estimated Prospect Contribution"
411
+ ,showlegend=False,
412
+ # plot_bgcolor='black',
413
+ # paper_bgcolor='black',
414
+ # font=dict(color='white'), # Changing font color to white for better contrast
415
+ xaxis=dict(
416
+ showgrid=False,
417
+ zeroline=False, # Hiding the x-axis zero line
418
+ ),
419
+ yaxis=dict(
420
+ title="Prospects",
421
+ showgrid=True,
422
+ gridcolor='lightgray',
423
+ griddash='dot', # Setting y-axis gridline color to gray
424
+ zeroline=False, # Hiding the y-axis zero line
425
+ # range=[18000, max(max(cumulative), max(values)) + 1000] # Setting the y-axis range from 19k to slightly above the maximum value
426
+ )
427
+ )
428
+ fig.add_annotation(
429
+ text=f"{start_date2.strftime('%m-%d-%Y')} to {end_date2.strftime('%m-%d-%Y')} vs. {start_date1.strftime('%m-%d-%Y')} To {end_date1.strftime('%m-%d-%Y')}",
430
+ x=0,
431
+ y=1.15,
432
+ xref="x domain",
433
+ yref="y domain",
434
+ showarrow=False,
435
+ font=dict(size=16),
436
+ # align='left'
437
+ )
438
+ # fig.update_xaxes(
439
+ # tickmode="array",
440
+ # # categoryorder="total ascending",
441
+ # tickvals=[f"{abs(values[i])}"],
442
+ # ticktext=[f"{abs(values[i])}"],
443
+ # ticklabelposition="outside",
444
+ # tickfont=dict(color="white"),
445
+ # )
446
+ else :
447
+ fig.update_layout(
448
+ showlegend=False,
449
+ # plot_bgcolor='black',
450
+ # paper_bgcolor='black',
451
+ # font=dict(color='white'), # Changing font color to white for better contrast
452
+ xaxis=dict(
453
+ showgrid=False,
454
+ zeroline=False, # Hiding the x-axis zero line
455
+ ),
456
+ yaxis=dict(
457
+ title="Prospects",
458
+ showgrid=True,
459
+ gridcolor='lightgray',
460
+ griddash='dot', # Setting y-axis gridline color to gray
461
+ zeroline=False, # Hiding the y-axis zero line
462
+ # range=[10000, max(cumulative)+1000] # Setting the y-axis range from 19k to slightly above the maximum value
463
+ )
464
+
465
+ )
466
+ fig.add_annotation(
467
+ text=f"{start_date_prev.strftime('%m-%d-%Y')} to {end_date_prev.strftime('%m-%d-%Y')} vs. {start_date.strftime('%m-%d-%Y')} To {end_date.strftime('%m-%d-%Y')}",
468
+ x=0,
469
+ y=1.15,
470
+ xref="x domain",
471
+ yref="y domain",
472
+ showarrow=False,
473
+ font=dict(size=16),
474
+ # align='left'
475
+ )
476
+ # # # # print(cur_data)
477
+ # # # # print(prev_data)
478
+ # fig.show()
479
+ return fig
480
+ def waterfall(start_date,end_date,btn_chart):
481
+ # if pd.isnull(start_date) == True :
482
+ # start_date = datetime(2024, 1, 28)
483
+ # if pd.isnull(end_date) == True :
484
+ # end_date = datetime(2024, 2, 24)
485
+ # start_date = datetime.strptime(start_date, "%Y-%m-%d")
486
+ # end_date = datetime.strptime(end_date, "%Y-%m-%d")
487
+ # start_date = start_date.datetime.data
488
+ # end_date = end_date.datetime.data
489
+ start_date = pd.to_datetime(start_date)
490
+ end_date = pd.to_datetime(end_date)
491
+
492
+ if btn_chart == "Month on Month":
493
+ start_date_prev = start_date +timedelta(weeks=-4)
494
+ end_date_prev = start_date +timedelta(days=-1)
495
+ else:
496
+ start_date_prev = start_date +timedelta(weeks=-52)
497
+ end_date_prev = start_date_prev +timedelta(weeks=4) +timedelta(days=-1)
498
+
499
+
500
+ # if start_date_prev < df['Date'].min() :
501
+ # return "a"
502
+
503
+ prev_data = df[(df['Date'] >= start_date_prev) & (df['Date'] <= end_date_prev)]
504
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
505
+
506
+
507
+ # Example data for the waterfall chart
508
+ data = [
509
+ {'label': 'Previous Period', 'value': round(prev_data[contribution_cols].values.sum())},
510
+ {'label': 'Broadcast TV', 'value': round(cur_data['Broadcast TV_Prospects'].sum()-prev_data['Broadcast TV_Prospects'].sum())},
511
+ {'label': 'Cable TV', 'value': round(cur_data['Cable TV_Prospects'].sum()-prev_data['Cable TV_Prospects'].sum())},
512
+ {'label': 'Connected & OTT TV', 'value': round(cur_data['Connected & OTT TV_Prospects'].sum()-prev_data['Connected & OTT TV_Prospects'].sum())},
513
+ {'label': 'Video', 'value': round(cur_data['Video_Prospects'].sum()-prev_data['Video_Prospects'].sum())},
514
+ {'label': 'Display Prospecting', 'value': round(cur_data['Display Prospecting_Prospects'].sum()-prev_data['Display Prospecting_Prospects'].sum())},
515
+ {'label': 'Display Retargeting', 'value': round(cur_data['Display Retargeting_Prospects'].sum()-prev_data['Display Retargeting_Prospects'].sum())},
516
+ {'label': 'Social Prospecting', 'value': round(cur_data['Social Prospecting_Prospects'].sum()-prev_data['Social Prospecting_Prospects'].sum())},
517
+ {'label': 'Social Retargeting', 'value': round(cur_data['Social Retargeting_Prospects'].sum()-prev_data['Social Retargeting_Prospects'].sum())},
518
+ {'label': 'Search Brand', 'value': round(cur_data['Search Brand_Prospects'].sum()-prev_data['Search Brand_Prospects'].sum())},
519
+ {'label': 'Search Non-brand', 'value': round(cur_data['Search Non-brand_Prospects'].sum()-prev_data['Search Non-brand_Prospects'].sum())},
520
+ {'label': 'Digital Partners', 'value': round(cur_data['Digital Partners_Prospects'].sum()-prev_data['Digital Partners_Prospects'].sum())},
521
+ {'label': 'Audio', 'value': round(cur_data['Audio_Prospects'].sum()-prev_data['Audio_Prospects'].sum())},
522
+ {'label': 'Email', 'value': round(cur_data['Email_Prospects'].sum()-prev_data['Email_Prospects'].sum())},
523
+ {'label': 'Current Period', 'value': round(cur_data[contribution_cols].values.sum())}
524
+ ]
525
+
526
+ # Calculate cumulative values for the waterfall chart
527
+ cumulative = [0]
528
+ for i in range(len(data)):
529
+ cumulative.append(cumulative[-1] + data[i]['value'])
530
+
531
+ # Adjusting values to start from zero for both first and last columns
532
+ cumulative[-1] = 0 # Set the last cumulative value to zero
533
+
534
+ # Extracting labels and values
535
+ labels = [item['label'] for item in data]
536
+ values = [item['value'] for item in data]
537
+
538
+ # Plotting the waterfall chart using go.Bar
539
+ bars = []
540
+ for i in range(len(data)):
541
+ color = '#4A88D9' if i == 0 or i == len(data) - 1 else '#DC5537' # Blue for first and last, gray for others
542
+ hover_text = f"<b>{labels[i]}</b><br>Value: {abs(values[i])}"
543
+
544
+ bars.append(go.Bar(
545
+ x=[labels[i]],
546
+ y=[cumulative[i+1] - cumulative[i]],
547
+ base=[cumulative[i]],
548
+ text=[f"{abs(values[i]):,}"],
549
+ textposition='auto',
550
+ hovertemplate=hover_text,
551
+ marker=dict(color=color),
552
+ showlegend=False
553
+ ))
554
+
555
+ # Creating the figure
556
+ fig = go.Figure(data=bars)
557
+
558
+ # Updating layout for black background and gray gridlines
559
+ if btn_chart == "Month on Month":
560
+ fig.update_layout(
561
+ title=f"Change In MMM Estimated Prospect Contribution"
562
+ ,showlegend=False,
563
+ # plot_bgcolor='black',
564
+ # paper_bgcolor='black',
565
+ # font=dict(color='white'), # Changing font color to white for better contrast
566
+ xaxis=dict(
567
+ showgrid=False,
568
+ zeroline=False, # Hiding the x-axis zero line
569
+ ),
570
+ yaxis=dict(
571
+ title="Prospects",
572
+ showgrid=True,
573
+ gridcolor='lightgray',
574
+ griddash='dot', # Setting y-axis gridline color to gray
575
+ zeroline=False, # Hiding the y-axis zero line
576
+ # range=[18000, max(max(cumulative), max(values)) + 1000] # Setting the y-axis range from 19k to slightly above the maximum value
577
+ )
578
+ )
579
+ fig.add_annotation(
580
+ text=f"{start_date_prev.strftime('%m-%d-%Y')} to {end_date_prev.strftime('%m-%d-%Y')} vs. {start_date.strftime('%m-%d-%Y')} To {end_date.strftime('%m-%d-%Y')}",
581
+ x=0,
582
+ y=1.15,
583
+ xref="x domain",
584
+ yref="y domain",
585
+ showarrow=False,
586
+ font=dict(size=16),
587
+ # align='left'
588
+ )
589
+ # fig.update_xaxes(
590
+ # tickmode="array",
591
+ # # categoryorder="total ascending",
592
+ # tickvals=[f"{abs(values[i])}"],
593
+ # ticktext=[f"{abs(values[i])}"],
594
+ # ticklabelposition="outside",
595
+ # tickfont=dict(color="white"),
596
+ # )
597
+ else :
598
+ fig.update_layout(
599
+ showlegend=False,
600
+ # plot_bgcolor='black',
601
+ # paper_bgcolor='black',
602
+ # font=dict(color='white'), # Changing font color to white for better contrast
603
+ xaxis=dict(
604
+ showgrid=False,
605
+ zeroline=False, # Hiding the x-axis zero line
606
+ ),
607
+ yaxis=dict(
608
+ title="Prospects",
609
+ showgrid=True,
610
+ gridcolor='lightgray',
611
+ griddash='dot', # Setting y-axis gridline color to gray
612
+ zeroline=False, # Hiding the y-axis zero line
613
+ # range=[10000, max(cumulative)+1000] # Setting the y-axis range from 19k to slightly above the maximum value
614
+ )
615
+
616
+ )
617
+ fig.add_annotation(
618
+ text=f"{start_date_prev.strftime('%m-%d-%Y')} to {end_date_prev.strftime('%m-%d-%Y')} vs. {start_date.strftime('%m-%d-%Y')} To {end_date.strftime('%m-%d-%Y')}",
619
+ x=0,
620
+ y=1.15,
621
+ xref="x domain",
622
+ yref="y domain",
623
+ showarrow=False,
624
+ font=dict(size=16),
625
+ # align='left'
626
+ )
627
+ # # # # print(cur_data)
628
+ # # # # print(prev_data)
629
+ # fig.show()
630
+ return fig
631
+
632
+ def shares_df_func(start_date,end_date):
633
+ # if pd.isnull(start_date) == True :
634
+ # start_date = datetime(2024, 1, 28)
635
+ # if pd.isnull(end_date) == True :
636
+ # end_date = datetime(2024, 2, 24)
637
+
638
+ start_date = pd.to_datetime(start_date)
639
+ end_date = pd.to_datetime(end_date)
640
+
641
+ start_date_prev = start_date +timedelta(weeks=-4)
642
+ end_date_prev = start_date +timedelta(days=-1)
643
+
644
+ prev_data = df[(df['Date'] >= start_date_prev) & (df['Date'] <= end_date_prev)]
645
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
646
+ cur_df1 = pd.DataFrame(cur_data[spend_cols].sum()).reset_index()
647
+ cur_df2 = pd.DataFrame(cur_data[metric_cols].sum()).reset_index()
648
+ cur_df3 = pd.DataFrame(cur_data[contribution_cols].sum()).reset_index()
649
+
650
+ cur_df1.columns = ["channels","cur_total_spend"]
651
+ cur_df2.columns = ["channels","cur_total_support"]
652
+ cur_df3.columns = ["channels","cur_total_contributions"]
653
+ cur_df1["channels"] = channels
654
+ cur_df2["channels"] = channels
655
+ cur_df3["channels"] = channels
656
+
657
+ cur_df1["cur_spend_share"] = (cur_df1["cur_total_spend"]/cur_df1["cur_total_spend"].sum())*100
658
+ cur_df2["cur_support_share"] = (cur_df2["cur_total_support"]/cur_df2["cur_total_support"].sum())*100
659
+ cur_df3["cur_contributions_share"] = (cur_df3["cur_total_contributions"]/cur_df3["cur_total_contributions"].sum())*100
660
+
661
+ prev_df1 = pd.DataFrame(prev_data[spend_cols].sum()).reset_index()
662
+ prev_df2 = pd.DataFrame(prev_data[metric_cols].sum()).reset_index()
663
+ prev_df3 = pd.DataFrame(prev_data[contribution_cols].sum()).reset_index()
664
+
665
+ prev_df1.columns = ["channels","prev_total_spend"]
666
+ prev_df2.columns = ["channels","prev_total_support"]
667
+ prev_df3.columns = ["channels","prev_total_contributions"]
668
+
669
+ prev_df1["channels"] = channels
670
+ prev_df2["channels"] = channels
671
+ prev_df3["channels"] = channels
672
+
673
+ prev_df1["prev_spend_share"] = (prev_df1["prev_total_spend"]/prev_df1["prev_total_spend"].sum())*100
674
+ prev_df2["prev_support_share"] = (prev_df2["prev_total_support"]/prev_df2["prev_total_support"].sum())*100
675
+ prev_df3["prev_contributions_share"] = (prev_df3["prev_total_contributions"]/prev_df3["prev_total_contributions"].sum())*100
676
+
677
+ cur_df = cur_df1.merge(cur_df2,on="channels",how = "inner")
678
+ cur_df = cur_df.merge(cur_df3,on="channels",how = "inner")
679
+
680
+ prev_df = prev_df1.merge(prev_df2,on="channels",how = "inner")
681
+ prev_df = prev_df.merge(prev_df3,on="channels",how = "inner")
682
+
683
+ shares_df = cur_df.merge(prev_df,on = "channels",how = "inner")
684
+ shares_df["Contribution Change"] = (-shares_df["prev_contributions_share"]+shares_df["cur_contributions_share"])/shares_df["prev_contributions_share"]
685
+ shares_df["Support Change"] = (-shares_df["prev_support_share"]+shares_df["cur_support_share"])/shares_df["prev_support_share"]
686
+ shares_df["Spend Change"] = (-shares_df["prev_spend_share"]+shares_df["cur_spend_share"])/shares_df["prev_spend_share"]
687
+ shares_df["Efficiency Index"] = shares_df["cur_contributions_share"]/shares_df["cur_spend_share"]
688
+ shares_df["Effectiveness Index"] = shares_df["cur_support_share"]/shares_df["cur_spend_share"]
689
+ return shares_df
690
+
691
+ def waterfall_table_func(shares_df):
692
+ ### waterfall delta table
693
+ # if pd.isnull(start_date) == True :
694
+ # start_date = datetime(2024, 1, 28)
695
+ # if pd.isnull(end_date) == True :
696
+ # end_date = datetime(2024, 2, 24)
697
+
698
+ waterfall_delta_df = shares_df[["channels","Contribution Change","Support Change","Spend Change"]]
699
+ waterfall_delta_df = waterfall_delta_df.rename(columns = {"channels":"METRIC"})
700
+ waterfall_delta_df.index = waterfall_delta_df["METRIC"]
701
+ waterfall_delta_df = waterfall_delta_df.round(2)
702
+ return (waterfall_delta_df[["Contribution Change","Support Change","Spend Change"]].transpose())
703
+
704
+
705
+ def channel_contribution(start_date,end_date):
706
+
707
+ # if pd.isnull(start_date) == True :
708
+ # start_date = datetime(2024, 1, 28)
709
+ # if pd.isnull(end_date) == True :
710
+ # end_date = datetime(2024, 2, 24)
711
+
712
+ start_date = pd.to_datetime(start_date)
713
+ end_date = pd.to_datetime(end_date)
714
+
715
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
716
+
717
+ channel_df = pd.DataFrame(cur_data[contribution_cols].sum()).reset_index()
718
+ channel_df.columns = ["channels","contributions"]
719
+ channel_df["channels"] = channels
720
+
721
+ # Creating the bar chart
722
+ fig = go.Figure(data=[go.Bar(
723
+ x=channel_df['channels'],
724
+ y=round(channel_df['contributions']),
725
+ marker=dict(color='rgb(74, 136, 217)'), # Blue color for all bars
726
+ text=(channel_df['contributions']).astype(int).apply(lambda x: f"{x:,}"),
727
+ textposition='outside'
728
+ )])
729
+
730
+ # Updating layout for better visualization
731
+ fig.update_layout(
732
+
733
+ # title=f"Media Contribution",
734
+ # plot_bgcolor='black',
735
+ # paper_bgcolor='black',
736
+ # font=dict(color='white'), # Changing font color to white for better contrast
737
+ title=
738
+ {
739
+ 'text': "Media Contribution",
740
+ 'font': {
741
+ 'size': 28,
742
+ 'family': 'Arial',
743
+ 'color': 'black',
744
+ # 'bold': True
745
+ }
746
+ },
747
+ xaxis=dict(
748
+ showgrid=False,
749
+ gridcolor='gray', # Setting x-axis gridline color to gray
750
+ zeroline=False, # Hiding the x-axis zero line
751
+ ),
752
+ yaxis=dict(
753
+ title="Prospect",
754
+ showgrid=True,
755
+ gridcolor='lightgray',
756
+ griddash='dot', # Setting y-axis gridline color to gray
757
+ zeroline=False, # Hiding the y-axis zero line
758
+ )
759
+ )
760
+
761
+
762
+ fig.add_annotation(
763
+ text=f"{start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}",
764
+ x=0,
765
+ y=1.15,
766
+ xref="x domain",
767
+ yref="y domain",
768
+ showarrow=False,
769
+ font=dict(size=16),
770
+ # align='left'
771
+ )
772
+
773
+ return fig
774
+
775
+ def chanel_spends(start_date,end_date):
776
+
777
+ # if pd.isnull(start_date) == True :
778
+ # start_date = datetime(2024, 1, 28)
779
+ # if pd.isnull(end_date) == True :
780
+ # end_date = datetime(2024, 2, 24)
781
+
782
+ start_date = pd.to_datetime(start_date)
783
+ end_date = pd.to_datetime(end_date)
784
+
785
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
786
+
787
+ channel_df = pd.DataFrame(cur_data[spend_cols].sum()).reset_index()
788
+ channel_df.columns = ["channels","spends"]
789
+ channel_df["channels"] = channels
790
+
791
+ # Creating the bar chart
792
+ fig = go.Figure(data=[go.Bar(
793
+ x=channel_df['channels'],
794
+ y=round(channel_df['spends']),
795
+ marker=dict(color='rgb(74, 136, 217)'), # Blue color for all bars
796
+ text=channel_df['spends'].apply(numerize),
797
+ # text = (channel_df['spends']).astype(int).apply(lambda x: f"{x:,}"),
798
+ textposition='outside'
799
+ )])
800
+
801
+ # Updating layout for better visualization
802
+ fig.update_layout(
803
+ # title=f"Media Spends",
804
+ # plot_bgcolor='black',
805
+ # paper_bgcolor='black',
806
+ # font=dict(color='white'), # Changing font color to white for better contrast
807
+ title=
808
+ {
809
+ 'text': "Media Spends",
810
+ 'font': {
811
+ 'size': 28,
812
+ 'family': 'Arial',
813
+ 'color': 'black',
814
+ # 'bold': True
815
+ }
816
+ },
817
+ xaxis=dict(
818
+ showgrid=False,
819
+ gridcolor='gray', # Setting x-axis gridline color to gray
820
+ zeroline=False, # Hiding the x-axis zero line
821
+ ),
822
+ yaxis=dict(
823
+ title="Spends ($)",
824
+ showgrid=True,
825
+ gridcolor='lightgray',
826
+ griddash='dot', # Setting y-axis gridline color to gray
827
+ zeroline=False, # Hiding the y-axis zero line
828
+ )
829
+ )
830
+ fig.add_annotation(
831
+ text=f"{start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}",
832
+ x=0,
833
+ y=1.15,
834
+ xref="x domain",
835
+ yref="y domain",
836
+ showarrow=False,
837
+ font=dict(size=16),
838
+ # align='left'
839
+ )
840
+
841
+ return fig
842
+
843
+ def shares_table_func(shares_df):
844
+
845
+ # if pd.isnull(start_date) == True :
846
+ # start_date = datetime(2024, 1, 28)
847
+ # if pd.isnull(end_date) == True :
848
+ # end_date = datetime(2024, 2, 24)
849
+
850
+ ### Shares tables
851
+ shares_table_df = shares_df[["channels","cur_spend_share","cur_support_share","cur_contributions_share","Efficiency Index","Effectiveness Index"]]
852
+ shares_table_df = shares_table_df.rename(columns = {"channels":"METRIC",
853
+ "cur_spend_share":"Spend Share",
854
+ "cur_support_share":"Support Share",
855
+ "cur_contributions_share":"Contribution Share"})
856
+ shares_table_df.index = shares_table_df["METRIC"]
857
+ for c in ["Spend Share","Support Share","Contribution Share"]:
858
+ shares_table_df[c] = shares_table_df[c].astype(int)
859
+ shares_table_df[c] = shares_table_df[c].astype(str)+'%'
860
+ for c in ["Efficiency Index","Effectiveness Index"]:
861
+ shares_table_df[c] = shares_table_df[c].round(2).astype(str)
862
+ shares_table_df = shares_table_df[["Spend Share","Support Share","Contribution Share","Efficiency Index","Effectiveness Index"]].transpose()
863
+ return (shares_table_df)
864
+
865
+ def eff_table_func(shares_df):
866
+
867
+ # if pd.isnull(start_date) == True :
868
+ # start_date = datetime(2024, 1, 28)
869
+ # if pd.isnull(end_date) == True :
870
+ # end_date = datetime(2024, 2, 24)
871
+
872
+ media_df = shares_df[['channels', 'cur_total_spend',"cur_total_support", "cur_total_contributions" ,'cur_spend_share',
873
+ 'cur_support_share', 'cur_contributions_share', 'Efficiency Index', 'Effectiveness Index']]
874
+ media_df = media_df.rename(columns = {"channels":"MEDIA",
875
+ "cur_total_spend":"TOTAL SPEND",
876
+ "cur_total_support":"TOTAL SUPPORT",
877
+ "cur_total_contributions":"TOTAL CONTRIBUTION",
878
+
879
+ "cur_spend_share":"SPEND SHARE",
880
+ "cur_support_share":"SUPPORT SHARE",
881
+ "cur_contributions_share":"CONTRIBUTION SHARE",
882
+ 'Efficiency Index':'EFFICIENCY INDEX',
883
+ 'Effectiveness Index' :'EFFECTIVENESS INDEX'
884
+ })
885
+
886
+ media_df.index = media_df["MEDIA"]
887
+ media_df.drop(columns = ["MEDIA"],inplace = True)
888
+ for c in ["TOTAL SPEND","TOTAL SUPPORT","TOTAL CONTRIBUTION"]:
889
+ media_df[c] = media_df[c].astype(int)
890
+ for c in ["SPEND SHARE","SUPPORT SHARE","CONTRIBUTION SHARE"]:
891
+ media_df[c] = media_df[c].astype(int)
892
+ media_df[c] = media_df[c].astype(str)+'%'
893
+ for c in ['EFFICIENCY INDEX','EFFECTIVENESS INDEX']:
894
+ media_df[c] = media_df[c].round(2).astype(str)
895
+ return (media_df)
896
+
897
+ def cpp(start_date,end_date):
898
+ # if pd.isnull(start_date) == True :
899
+ # start_date = datetime(2024, 1, 28)
900
+ # if pd.isnull(end_date) == True :
901
+ # end_date = datetime(2024, 2, 24)
902
+
903
+
904
+ start_date = pd.to_datetime(start_date)
905
+ end_date = pd.to_datetime(end_date)
906
+
907
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
908
+
909
+
910
+ fig = go.Figure()
911
+ colors = [
912
+ 'rgba(74, 136, 217, 0.8)', # Blue
913
+ 'rgba(220, 85, 55, 0.8)', # Red
914
+ 'rgba(67, 150, 80, 0.8)', # Green
915
+ 'rgba(237, 151, 35, 0.8)', # Orange
916
+ 'rgba(145, 68, 255, 0.8)', # Purple
917
+ 'rgba(128, 128, 128, 0.8)', # Gray
918
+ 'rgba(255, 165, 0, 0.8)', # Amber
919
+ 'rgba(255, 192, 203, 0.8)', # Pink
920
+ 'rgba(0, 191, 255, 0.8)', # Deep Sky Blue
921
+ 'rgba(127, 255, 0, 0.8)', # Chartreuse
922
+ 'rgba(255, 69, 0, 0.8)', # Red-Orange
923
+ 'rgba(75, 0, 130, 0.8)', # Indigo
924
+ 'rgba(240, 230, 140, 0.8)', # Khaki
925
+ 'rgba(218, 112, 214, 0.8)'
926
+ ]
927
+ colors = ['#ff2b2b', # Pastel Peach
928
+ '#0068c9', # Pastel Blue
929
+ '#83c9ff', # Pastel Pink
930
+
931
+ '#ffabab', # Pastel Purple
932
+ '#29b09d', # Pastel Green
933
+ '#7defa1', # Pastel Yellow
934
+ '#ff8700', # Pastel Gray
935
+ '#ffd16a', # Pastel Red
936
+ '#6d3fc0', # Pastel Rose
937
+ '#d5dae5', # Pastel Lavender
938
+ '#309bff', # Pastel Mauve
939
+ '#e9f5ff', # Pastel Beige
940
+ '#BEBADA' # Pastel Lilac
941
+ ]
942
+
943
+ for i in range(0,13):
944
+ cpp_df = cur_data[['Date',spend_cols[i],contribution_cols[i]]]
945
+ cpp_df[channels[i]+"_cpp"] = cpp_df[spend_cols[i]]/cpp_df[contribution_cols[i]]
946
+ # Add each line trace
947
+ fig.add_trace(go.Scatter(x=cpp_df['Date'], y=cpp_df[channels[i]+"_cpp"], mode='lines', name=channels[i], line=dict(color=colors[i])))
948
+
949
+ # Update layout for better visualization
950
+ fig.update_layout(
951
+ # title=f"CPP Distribution"
952
+ # ,
953
+ title=
954
+ {
955
+ 'text': "Cost Per Prospect Distribution",
956
+ 'font': {
957
+ 'size': 28,
958
+ 'family': 'Arial',
959
+ 'color': 'black',
960
+ # 'bold': True
961
+ }
962
+ },
963
+ # plot_bgcolor='black',
964
+ # paper_bgcolor='black',
965
+ # font=dict(color='white'), # Changing font color to white for better contrast
966
+ xaxis=dict(
967
+ showgrid=False,
968
+ gridcolor='lightgray',
969
+ griddash='dot', # Setting x-axis gridline color to gray
970
+ zeroline=False, # Hiding the x-axis zero line
971
+ ),
972
+ yaxis=dict(
973
+ title="CPP",
974
+ showgrid=True,
975
+ gridcolor='lightgray',
976
+ griddash='dot', # Setting y-axis gridline color to gray
977
+ zeroline=False, # Hiding the y-axis zero line
978
+ ),
979
+ hovermode='x' # Show hover info for all lines at a single point
980
+ )
981
+ fig.add_annotation(
982
+ text=f"{start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}",
983
+ x=0,
984
+ y=1.15,
985
+ xref="x domain",
986
+ yref="y domain",
987
+ showarrow=False,
988
+ font=dict(size=16),
989
+ # align='left'
990
+ )
991
+ return fig
992
+
993
+ def base_decomp():
994
+
995
+ # if pd.isnull(start_date) == True :
996
+ # start_date = datetime(2024, 1, 28)
997
+ # if pd.isnull(end_date) == True :
998
+ # end_date = datetime(2024, 2, 24)
999
+
1000
+ base_decomp_df = df[['Date','Unemployment', 'Competition','Trend','Seasonality','Base_0']]
1001
+ fig = go.Figure()
1002
+ colors = ['#ff2b2b', # Pastel Peach
1003
+ '#0068c9', # Pastel Blue
1004
+ '#83c9ff', # Pastel Pink
1005
+ ]
1006
+ # Add each line trace
1007
+ fig.add_trace(go.Scatter(x=base_decomp_df['Date'], y=base_decomp_df['Base_0'], mode='lines', name='Trend and Seasonality',line=dict(color=colors[0])))
1008
+ fig.add_trace(go.Scatter(x=base_decomp_df['Date'], y=base_decomp_df['Unemployment'], mode='lines', name='Unemployment',line=dict(color=colors[1])))
1009
+ fig.add_trace(go.Scatter(x=base_decomp_df['Date'], y=base_decomp_df['Competition'], mode='lines', name='Competition',line=dict(color=colors[2])))
1010
+
1011
+ # Update layout for better visualization
1012
+ fig.update_layout(
1013
+ # title=f"Base Decomposition"
1014
+ # <br>{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}"
1015
+ # ,
1016
+ # plot_bgcolor='black',
1017
+ # paper_bgcolor='black',
1018
+ # font=dict(color='white'), # Changing font color to white for better contrast
1019
+ title=
1020
+ {
1021
+ 'text': "Base Decomposition",
1022
+ 'font': {
1023
+ 'size': 28,
1024
+ 'family': 'Arial',
1025
+ 'color': 'black',
1026
+ # 'bold': True
1027
+ }
1028
+ },
1029
+ xaxis=dict(
1030
+ showgrid=False,
1031
+ gridcolor='gray', # Setting x-axis gridline color to gray
1032
+ zeroline=True, # Hiding the x-axis zero line
1033
+ ),
1034
+ yaxis=dict(
1035
+ title="Prospect",
1036
+ showgrid=True,
1037
+ gridcolor='lightgray',
1038
+ griddash='dot', # Setting y-axis gridline color to gray
1039
+ zeroline=False, # Hiding the y-axis zero line
1040
+ ),
1041
+ hovermode='x' # Show hover info for all lines at a single point
1042
+ )
1043
+ fig.add_annotation(
1044
+ text=f"{base_decomp_df['Date'].min().strftime('%m-%d-%Y')} to {(base_decomp_df['Date'].max()+timedelta(days=6)).strftime('%m-%d-%Y')}",
1045
+ x=0,
1046
+ y=1.15,
1047
+ xref="x domain",
1048
+ yref="y domain",
1049
+ showarrow=False,
1050
+ font=dict(size=16),
1051
+ # align='left'
1052
+ )
1053
+ return fig
1054
+
1055
+ def media_decomp():
1056
+ # if pd.isnull(start_date) == True :
1057
+ # start_date = datetime(2024, 1, 28)
1058
+ # if pd.isnull(end_date) == True :
1059
+ # end_date = datetime(2024, 2, 24)
1060
+
1061
+ df['base'] = df[ 'Base_0']+df['Unemployment']+df['Competition']
1062
+ cols = ['Date',
1063
+ 'base',
1064
+ 'Broadcast TV_Prospects',
1065
+ 'Cable TV_Prospects',
1066
+ 'Connected & OTT TV_Prospects',
1067
+ 'Video_Prospects',
1068
+ 'Display Prospecting_Prospects',
1069
+ 'Display Retargeting_Prospects',
1070
+ 'Social Prospecting_Prospects',
1071
+ 'Social Retargeting_Prospects',
1072
+ 'Search Brand_Prospects',
1073
+ 'Search Non-brand_Prospects',
1074
+ 'Digital Partners_Prospects',
1075
+ 'Audio_Prospects',
1076
+ 'Email_Prospects',
1077
+ ]
1078
+ media_decomp_df = df[cols]
1079
+
1080
+ # Calculating the cumulative sum for stacking
1081
+ cumulative_df = media_decomp_df.copy()
1082
+ # for channel in media_decomp_df.columns[1:]:
1083
+ # cumulative_df[channel] = cumulative_df[channel] + cumulative_df[channel].shift(1, fill_value=0)
1084
+
1085
+ media_cols = media_decomp_df.columns
1086
+ for i in range(2,len(media_cols)):
1087
+ # # # # print(media_cols[i])
1088
+ cumulative_df[media_cols[i]] = cumulative_df[media_cols[i]] + cumulative_df[media_cols[i-1]]
1089
+ # cumulative_df
1090
+
1091
+ # Creating the stacked area chart
1092
+ fig = go.Figure()
1093
+
1094
+ colors =colors = [
1095
+ 'rgba(74, 136, 217, 0.8)', # Blue
1096
+ 'rgba(220, 85, 55, 0.8)', # Red
1097
+ 'rgba(67, 150, 80, 0.8)', # Green
1098
+ 'rgba(237, 151, 35, 0.8)', # Orange
1099
+ 'rgba(145, 68, 255, 0.8)', # Purple
1100
+ 'rgba(128, 128, 128, 0.8)', # Gray
1101
+ 'rgba(255, 165, 0, 0.8)', # Amber
1102
+ 'rgba(255, 192, 203, 0.8)', # Pink
1103
+ 'rgba(0, 191, 255, 0.8)', # Deep Sky Blue
1104
+ 'rgba(127, 255, 0, 0.8)', # Chartreuse
1105
+ 'rgba(255, 69, 0, 0.8)', # Red-Orange
1106
+ 'rgba(75, 0, 130, 0.8)', # Indigo
1107
+ 'rgba(240, 230, 140, 0.8)', # Khaki
1108
+ 'rgba(218, 112, 214, 0.8)'
1109
+ ]
1110
+
1111
+ for idx, channel in enumerate(media_decomp_df.columns[1:]):
1112
+ fig.add_trace(go.Scatter(
1113
+ x=media_decomp_df['Date'],
1114
+ y=cumulative_df[channel],
1115
+ fill='tonexty' if idx > 0 else 'tozeroy', # Fill to the previous curve
1116
+ mode='none',
1117
+ name=str.split(channel,'_')[0],
1118
+ text=media_decomp_df[channel], # Adding text for each point
1119
+ hoverinfo='x+y+text',
1120
+ fillcolor=colors[idx] # Different color for each channel
1121
+ ))
1122
+
1123
+ # Updating layout for better visualization
1124
+ fig.update_layout(
1125
+ # title=f"Media Decomposition",# <br>{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}",
1126
+ title=
1127
+ {
1128
+ 'text': "Media Decomposition",
1129
+ 'font': {
1130
+ 'size': 28,
1131
+ 'family': 'Arial',
1132
+ 'color': 'black',
1133
+ # 'bold': True
1134
+ }
1135
+ },
1136
+ # plot_bgcolor='black',
1137
+ # paper_bgcolor='black',
1138
+ # font=dict(color='white'), # Changing font color to white for better contrast
1139
+ xaxis=dict(
1140
+ showgrid=False,
1141
+ gridcolor='gray', # Setting x-axis gridline color to gray
1142
+ zeroline=False, # Hiding the x-axis zero line
1143
+ ),
1144
+ yaxis=dict(
1145
+ title="Prospect",
1146
+ showgrid=True,
1147
+ gridcolor='lightgray',
1148
+ griddash='dot', # Setting y-axis gridline color to gray
1149
+ zeroline=False, # Hiding the y-axis zero line
1150
+ )
1151
+ )
1152
+ fig.add_annotation(
1153
+ text=f"{media_decomp_df['Date'].min().strftime('%m-%d-%Y')} to {(media_decomp_df['Date'].max()+timedelta(days=6)).strftime('%m-%d-%Y')}",
1154
+ x=0,
1155
+ y=1.15,
1156
+ xref="x domain",
1157
+ yref="y domain",
1158
+ showarrow=False,
1159
+ font=dict(size=16),
1160
+ # align='left'
1161
+ )
1162
+ return fig
1163
+
1164
+ def mmm_model_quality():
1165
+ base_df = df[['Date',"Y_hat","Y"]]
1166
+ fig = go.Figure()
1167
+
1168
+ # Add each line trace
1169
+ fig.add_trace(go.Scatter(x=base_df['Date'], y=base_df['Y_hat'], mode='lines', name='Predicted',line=dict(color='#CC5500') ))
1170
+ fig.add_trace(go.Scatter(x=base_df['Date'], y=base_df['Y'], mode='lines', name='Actual (Prospect)',line=dict(color='#4B88FF')))
1171
+
1172
+
1173
+ # Update layout for better visualization
1174
+ fig.update_layout(
1175
+ title={
1176
+ 'text': "Model Predicted v/s Actual Prospects",
1177
+ 'font': {
1178
+ 'size': 24,
1179
+ 'family': 'Arial',
1180
+ 'color': 'black',
1181
+ # 'bold': True
1182
+ }
1183
+ }
1184
+ # title=f"Model Predicted v/s Actual Prospects"
1185
+ ,
1186
+ # plot_bgcolor='black',
1187
+ # paper_bgcolor='black',
1188
+ # font=dict(color='white'), # Changing font color to white for better contrast
1189
+ xaxis=dict(
1190
+ showgrid=False,
1191
+ gridcolor='gray', # Setting x-axis gridline color to gray
1192
+ zeroline=False, # Hiding the x-axis zero line
1193
+ ),
1194
+ yaxis=dict(
1195
+ title="Prospects",
1196
+ showgrid=True,
1197
+ gridcolor='lightgray',
1198
+ griddash='dot', # Setting y-axis gridline color to gray
1199
+ zeroline=False, # Hiding the y-axis zero line
1200
+ ),
1201
+ hovermode='x' # Show hover info for all lines at a single point
1202
+ )
1203
+
1204
+ return(fig)
1205
+
1206
+ def media_data():
1207
+ # Path to your JSON file
1208
+ json_file_path = "all_solutions_2024-05-09.json"
1209
+ # Read the JSON file
1210
+ with open(json_file_path, 'r') as file:
1211
+ json_data = json.load(file)
1212
+
1213
+ # Initialize a list to store the extracted data
1214
+ extracted_data = []
1215
+
1216
+ # Extract half_life and coeff from media_params
1217
+ for params_type in ["control_params","other_params","media_params"]:
1218
+ for media, params in json_data['solution_0']['solution'][params_type].items():
1219
+ try:
1220
+ extracted_data.append({
1221
+ 'category': media,# str.split(params_type,'_')[0],
1222
+ 'half_life': params['half_life'],
1223
+ 'coeff': params['coeff']
1224
+ })
1225
+ except:
1226
+ extracted_data.append({
1227
+ 'category':media,# str.split(params_type,'_')[0],
1228
+ 'half_life': None,
1229
+ 'coeff': params['coeff']
1230
+ })
1231
+
1232
+ media_df = pd.DataFrame(extracted_data)
1233
+ return media_df
1234
+
1235
+ def elasticity_and_media(media_df):
1236
+ # Create subplots
1237
+ fig = make_subplots(rows=1, cols=2, subplot_titles=("Chart 1", "Chart 2"))
1238
+ fig.add_trace(
1239
+ go.Bar(
1240
+ x=media_df['coeff'],
1241
+ y=media_df['category'],
1242
+ orientation='h', # Setting the orientation to horizontal
1243
+ marker_color='rgba(75, 136, 257, 1)',
1244
+ text= media_df['coeff'].round(2),
1245
+ textposition="outside"
1246
+ ),row=1, col=1
1247
+ )
1248
+
1249
+ fig.add_trace(
1250
+ go.Bar(
1251
+ x=media_df[media_df['half_life'].isnull()==False]['half_life'],
1252
+ y=media_df[media_df['half_life'].isnull()==False]['category'],
1253
+ orientation='h', # Setting the orientation to horizontal
1254
+ marker_color='rgba(75, 136, 257, 1)',
1255
+ # text= media_df[media_df['half_life'].isnull()==False]['half_life'].round(2),
1256
+ textposition="outside"
1257
+ ),row=1, col=2
1258
+ )
1259
+ fig.update_layout(
1260
+ margin=dict(l=40, r=40, t=40, b=40), # Adjust the margins
1261
+ )
1262
+
1263
+ return fig
1264
+
1265
+ def elasticity(media_df):
1266
+ fig = go.Figure()
1267
+ # media_df = media_df[["category","coeff"]]
1268
+ fig.add_trace(go.Bar(
1269
+
1270
+ x=media_df['coeff'],
1271
+ y=media_df['category'],
1272
+ orientation='h', # Setting the orientation to horizontal
1273
+ marker_color='rgba(75, 136, 257, 1)',
1274
+ text= media_df['coeff'].round(2),
1275
+ textposition="outside"
1276
+ ))
1277
+
1278
+ # Updating layout for better visualization
1279
+ fig.update_layout(
1280
+ title={
1281
+ 'text': "Media And Baseline Elasticity",
1282
+ 'font': {
1283
+ 'size': 24,
1284
+ 'family': 'Arial',
1285
+ 'color': 'black',
1286
+ # 'bold': True
1287
+ }
1288
+ }
1289
+
1290
+ ,
1291
+ # title="Media And Baseline Elasticity",
1292
+ xaxis=dict(
1293
+ title="Elasticity (coefficient)",
1294
+ showgrid=True,
1295
+ gridcolor='lightgray',
1296
+ griddash='dot', # Setting x-axis gridline color to gray
1297
+ zeroline=False, # Hiding the x-axis zero line
1298
+ ),
1299
+ yaxis=dict(
1300
+
1301
+ showgrid=False,
1302
+ gridcolor='gray', # Setting y-axis gridline color to gray
1303
+ zeroline=False, # Hiding the y-axis zero line
1304
+ ),
1305
+ margin=dict(r=10)
1306
+ # plot_bgcolor='black',
1307
+ # paper_bgcolor='black',
1308
+ # font=dict(color='lightgray') # Changing font color to white for better contrast
1309
+ )
1310
+ return fig
1311
+
1312
+
1313
+
1314
+
1315
+
1316
+
1317
+ def half_life(media_df):
1318
+ fig = go.Figure()
1319
+ # media_df = media_df[["category","coeff"]]
1320
+ fig.add_trace(go.Bar(
1321
+
1322
+ x=media_df[media_df['half_life'].isnull()==False]['half_life'],
1323
+ y=media_df[media_df['half_life'].isnull()==False]['category'],
1324
+ orientation='h', # Setting the orientation to horizontal
1325
+ marker_color='rgba(75, 136, 257, 1)',
1326
+ text= media_df[media_df['half_life'].isnull()==False]['half_life'].round(2),
1327
+ textposition="outside"
1328
+ ))
1329
+
1330
+ # Updating layout for better visualization
1331
+ fig.update_layout(
1332
+ title={
1333
+ 'text': "Media Half-life",
1334
+ 'font': {
1335
+ 'size': 24,
1336
+ 'family': 'Arial',
1337
+ 'color': 'black',
1338
+ # 'bold': True
1339
+ }
1340
+ }
1341
+
1342
+ ,
1343
+ xaxis=dict(
1344
+ title="Weeks",
1345
+ showgrid=True,
1346
+ gridcolor='lightgray',
1347
+ griddash='dot', # Setting x-axis gridline color to gray
1348
+ zeroline=False, # Hiding the x-axis zero line
1349
+ ),
1350
+ yaxis=dict(
1351
+
1352
+ showgrid=False,
1353
+ gridcolor='gray', # Setting y-axis gridline color to gray
1354
+ zeroline=False, # Hiding the y-axis zero line
1355
+ ),margin=dict(l=20)
1356
+ # plot_bgcolor='black',
1357
+ # paper_bgcolor='black',
1358
+ # font=dict(color='lightgray') # Changing font color to white for better contrast
1359
+ )
1360
+ return fig
1361
+
1362
+
1363
+ # media metrics table
1364
+ n = 104
1365
+ k = 18
1366
+
1367
+ def calculate_aic(y, y_hat):
1368
+ n = len(y)
1369
+ sse = np.sum((y - y_hat) ** 2)
1370
+ aic = n * np.log(sse / n) + 2 * k
1371
+ return aic
1372
+
1373
+ def calculate_bic(y, y_hat):
1374
+ n = len(y)
1375
+ sse = np.sum((y - y_hat) ** 2)
1376
+ bic = n * np.log(sse / n) + k * np.log(n)
1377
+ return bic
1378
+ def calculate_r_squared(y, y_hat):
1379
+ ss_total = np.sum((y - np.mean(y)) ** 2)
1380
+ ss_residual = np.sum((y - y_hat) ** 2)
1381
+ r_squared = 1 - (ss_residual / ss_total)
1382
+ return r_squared
1383
+
1384
+ # Function to calculate Adjusted R-squared
1385
+ def calculate_adjusted_r_squared(y, y_hat):
1386
+ n = len(y)
1387
+ r_squared = calculate_r_squared(y, y_hat)
1388
+ adjusted_r_squared = 1 - ((1 - r_squared) * (n - 1) / (n - k - 1))
1389
+ return adjusted_r_squared
1390
+
1391
+ # Function to calculate MAPE
1392
+ def calculate_mape(y, y_hat):
1393
+ mape = np.mean(np.abs((y - y_hat) / y)) * 100
1394
+ return mape
1395
+
1396
+ def model_metrics_table_func():
1397
+ model_metrics_df = pd.DataFrame([calculate_r_squared(df["Y"], df["Y_hat"]),
1398
+ calculate_adjusted_r_squared(df["Y"], df["Y_hat"]),
1399
+ calculate_mape(df["Y"], df["Y_hat"]),
1400
+ calculate_aic(df["Y"], df["Y_hat"]),
1401
+ calculate_bic(df["Y"], df["Y_hat"])])
1402
+ model_metrics_df.index = ["R-squared","Adjusted R-squared","MAPE","AIC","BIC"]
1403
+ model_metrics_df = model_metrics_df.transpose()
1404
+ # model_metrics_df.index = model_metrics_df["R-squared"]
1405
+ # model_metrics_df = model_metrics_df.drop(columns=["R-squared"])
1406
+ model_metrics_df2 = pd.DataFrame(model_metrics_df.values,columns=["R-squared","Adjusted R-squared","MAPE","AIC","BIC"] )
1407
+
1408
+ # model_metrics_df2 = model_metrics_df2.round(2)
1409
+ model_metrics_df2["R-squared"] = model_metrics_df2["R-squared"].apply(lambda x: "{:.2%}".format(x))
1410
+ model_metrics_df2["Adjusted R-squared"] = model_metrics_df2["Adjusted R-squared"].apply(lambda x: "{:.2%}".format(x))
1411
+ model_metrics_df2["MAPE"] = (model_metrics_df2["MAPE"]/100).apply(lambda x: "{:.2%}".format(x))
1412
+ model_metrics_df2["AIC"] = model_metrics_df2["AIC"].round(0)
1413
+ model_metrics_df2["BIC"] = model_metrics_df2["BIC"].round(0)
1414
+ model_metrics_df2.index = [" "]
1415
+ # model_metrics_df2 = model_metrics_df2.reset_index(drop = True)
1416
+ return model_metrics_df2
1417
+
1418
+ def get_month_name(month_number):
1419
+
1420
+ months = ["January", "February", "March", "April", "May", "June",
1421
+ "July", "August", "September", "October", "November", "December"]
1422
+ if 1 <= month_number <= 12:
1423
+ return months[month_number - 1]
1424
+ else:
1425
+ return "Invalid month number"
1426
+
1427
+
1428
+
1429
+ def scenario_spend_forecasting(delta_df,start_date,end_date):
1430
+
1431
+ key_df = pd.DataFrame()
1432
+ key_df["Channel_name"] = ["Email",
1433
+ "DisplayRetargeting",
1434
+ "\xa0Video",
1435
+ "BroadcastTV",
1436
+ "SocialRetargeting",
1437
+ "Connected&OTTTV",
1438
+ "SearchBrand",
1439
+ "Audio",
1440
+ "SocialProspecting",
1441
+ "CableTV",
1442
+ "DisplayProspecting",
1443
+ "SearchNon-brand",
1444
+ "DigitalPartners"]
1445
+ key_df["Channels"] = [
1446
+ "EMAIL",
1447
+ "DISPLAY RETARGETING",
1448
+ "VIDEO",
1449
+ "BROADCAST TV",
1450
+ "SOCIAL RETARGETING",
1451
+ "CONNECTED & OTT TV",
1452
+ "SEARCH BRAND",
1453
+ "AUDIO",
1454
+ "SOCIAL PROSPECTING",
1455
+ "CABLE TV",
1456
+ "DISPLAY PROSPECTING",
1457
+ "SEARCH NON-BRAND",
1458
+ "DIGITAL PARTNERS"
1459
+ ]
1460
+
1461
+
1462
+ start_date = pd.to_datetime(start_date)
1463
+ end_date = pd.to_datetime(end_date)
1464
+
1465
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
1466
+ cur_data["Month"] = cur_data["Date"].dt.month
1467
+ # cur_data["Year"] = cur_data["Date"].dt.year
1468
+ cur_data["Month year"] = cur_data["Month"].apply(get_month_name) + ' ' +(cur_data["Date"].dt.year+1).astype(str)
1469
+ grp_cols = ['tv_broadcast_spend',
1470
+ 'tv_cable_spend',
1471
+ 'stream_video_spend',
1472
+ 'olv_spend',
1473
+ 'disp_prospect_spend',
1474
+ 'disp_retarget_spend',
1475
+ 'social_prospect_spend',
1476
+ 'social_retarget_spend',
1477
+ 'search_brand_spend',
1478
+ 'search_nonbrand_spend',
1479
+ 'cm_spend',
1480
+ 'audio_spend',
1481
+ 'email_spend',
1482
+ "Month",
1483
+ "Month year"]
1484
+
1485
+ data2 = cur_data[grp_cols].groupby("Month year").sum()
1486
+
1487
+ data2.columns = [
1488
+ 'BROADCAST TV',
1489
+ 'CABLE TV',
1490
+ 'CONNECTED & OTT TV',
1491
+ 'VIDEO',
1492
+ 'DISPLAY PROSPECTING',
1493
+ 'DISPLAY RETARGETING',
1494
+ 'SOCIAL PROSPECTING',
1495
+ 'SOCIAL RETARGETING',
1496
+ 'SEARCH BRAND',
1497
+ 'SEARCH NON-BRAND',
1498
+ 'DIGITAL PARTNERS',
1499
+ 'AUDIO',
1500
+ 'EMAIL',
1501
+ "Month"]
1502
+ data2 = data2.sort_values("Month")
1503
+ data2.drop(columns = ["Month"], inplace = True)
1504
+
1505
+ key_df = pd.DataFrame()
1506
+ key_df["Channel_name"] = ["Email","DisplayRetargeting","\xa0Video","BroadcastTV","SocialRetargeting","Connected&OTTTV","SearchBrand","Audio","SocialProspecting","CableTV","DisplayProspecting","SearchNon-brand","DigitalPartners"]
1507
+ key_df["Channels"] = ["EMAIL","DISPLAY RETARGETING","VIDEO","BROADCAST TV","SOCIAL RETARGETING","CONNECTED & OTT TV","SEARCH BRAND","AUDIO","SOCIAL PROSPECTING","CABLE TV","DISPLAY PROSPECTING","SEARCH NON-BRAND","DIGITAL PARTNERS"]
1508
+ delta_df = delta_df.merge(key_df,on = "Channel_name",how = "inner")
1509
+ # # print(delta_df)
1510
+
1511
+ data3 = data2.copy()
1512
+ for channel in delta_df["Channels"]:
1513
+ # # print(channel)
1514
+ delta_percent = delta_df[delta_df["Channels"]==channel]["Delta_percent"].iloc[0]
1515
+ # # print(delta_percent)
1516
+ data3[channel] = data3[channel]*(1+delta_percent/100)
1517
+ # # print(data2)
1518
+ # # print(data3)
1519
+
1520
+
1521
+ ###### output dataframes
1522
+ output_df2 = data3.copy()
1523
+
1524
+ #### percent change dataframe
1525
+ delta_df2 = pd.DataFrame(data = delta_df["Delta_percent"].values,index = delta_df["Channels"])
1526
+ # # print(delta_df2)
1527
+ output_df1 = (pd.DataFrame(data2.sum()).transpose()).append(pd.DataFrame(data3.sum()).transpose()).append(delta_df2.transpose())
1528
+ output_df1.index = ["Last Year Spends", "Forecasted Spends","Spends Change"]
1529
+
1530
+
1531
+
1532
+ # # print(output_df1)
1533
+ #
1534
+
1535
+
1536
+
1537
+ # # print (data3)
1538
+ # data3 = data2.append(key_df)
1539
+ # # print (data2)
1540
+ # cur_data = cur_data[spend_cols]
1541
+ # cur_data.columns = channels
1542
+ # data1 = pd.DataFrame(cur_data[channels].sum().transpose()).reset_index()
1543
+ # data1.columns = ["Channels","last_year_spends"]
1544
+
1545
+ # df_modified = delta_df.merge(key_df,on = "Channel_name",how = "inner")
1546
+ # df_modified2 = df_modified.merge(data1,on = "Channels",how ="outer")
1547
+ # # df_modified2["Forecasted Spends"] =( df_modified2["last_year_spends"]*(1+df_modified2["Delta_percent"]/100)).astype(int)
1548
+ # df_modified2["Forecasted Spends"] =( df_modified2["last_year_spends"]*(1+df_modified2["Delta_percent"]/100)).apply(lambda x: "${:,.0f}".format(x))
1549
+ # df_modified2.index = df_modified2["Channels"]
1550
+ # df_modified2["Spend Change"] = (df_modified2["Delta_percent"]/100).apply(lambda x: "{:.0%}".format(x))
1551
+ # # df_modified2["Forecasted Spends"] = df_modified2["Forecasted Spends"].astype(int)
1552
+ # df_modified2["Last Year Spends"] = df_modified2["last_year_spends"].apply(lambda x: "${:,.0f}".format(x))
1553
+ # df_modified3 = df_modified2[["Last Year Spends","Forecasted Spends","Spend Change"]].transpose()
1554
+ # # df_modified2["forecasted_spends"] =
1555
+ # # # df_modified = delta_percent
1556
+ # # # df_modified["Optimised Spends"] = df_modified["Current Spends"]*
1557
+ # df_modified3 = df_modified3[['BROADCAST TV', 'CABLE TV',
1558
+ # 'CONNECTED & OTT TV', 'VIDEO', 'DISPLAY PROSPECTING',
1559
+ # 'DISPLAY RETARGETING', 'SOCIAL PROSPECTING', 'SOCIAL RETARGETING',
1560
+ # 'SEARCH BRAND', 'SEARCH NON-BRAND', 'DIGITAL PARTNERS', 'AUDIO',
1561
+ # 'EMAIL']]
1562
+
1563
+ return output_df1,output_df2
1564
+
1565
+ def scenario_spend_forecasting2(delta_df,start_date,end_date):
1566
+
1567
+ key_df = pd.DataFrame()
1568
+ key_df["Channel_name"] = ["Email",
1569
+ "DisplayRetargeting",
1570
+ "\xa0Video",
1571
+ "BroadcastTV",
1572
+ "SocialRetargeting",
1573
+ "Connected&OTTTV",
1574
+ "SearchBrand",
1575
+ "Audio",
1576
+ "SocialProspecting",
1577
+ "CableTV",
1578
+ "DisplayProspecting",
1579
+ "SearchNon-brand",
1580
+ "DigitalPartners"]
1581
+ key_df["Channels"] = [
1582
+ "EMAIL",
1583
+ "DISPLAY RETARGETING",
1584
+ "VIDEO",
1585
+ "BROADCAST TV",
1586
+ "SOCIAL RETARGETING",
1587
+ "CONNECTED & OTT TV",
1588
+ "SEARCH BRAND",
1589
+ "AUDIO",
1590
+ "SOCIAL PROSPECTING",
1591
+ "CABLE TV",
1592
+ "DISPLAY PROSPECTING",
1593
+ "SEARCH NON-BRAND",
1594
+ "DIGITAL PARTNERS"
1595
+ ]
1596
+
1597
+ # import math
1598
+ # start_date = pd.to_datetime(start_date)
1599
+ # end_date = pd.to_datetime(end_date)
1600
+
1601
+ # cur_data = df[(df['Date'] >= start_date) & (df['Date'] < end_date)]
1602
+ # cur_data = cur_data[spend_cols2]
1603
+ # cur_data.columns = channels2
1604
+
1605
+ # cur_data["Date2"] = cur_data["Date"]+ pd.Timedelta(days=6)
1606
+ # cur_data["Month"] = cur_data["Date"].dt.month
1607
+
1608
+
1609
+ # # cur_data["Date"] = delta_df["Date"]
1610
+ # # cur_data["Date_diff"] = (cur_data["Date"]-start_date).dt.days
1611
+ # # cur_data["Date_diff_months"] =(np.ceil(cur_data["Date_diff"] / 30))
1612
+
1613
+ # data2 = cur_data.groupby("Month").agg({
1614
+ # 'BROADCAST TV':"sum",
1615
+ # 'CABLE TV':"sum",
1616
+ # 'CONNECTED & OTT TV':"sum",
1617
+ # 'VIDEO':"sum",
1618
+ # 'DISPLAY PROSPECTING':"sum",
1619
+ # 'DISPLAY RETARGETING':"sum",
1620
+ # 'SOCIAL PROSPECTING':"sum",
1621
+ # 'SOCIAL RETARGETING':"sum",
1622
+ # 'SEARCH BRAND':"sum",
1623
+ # 'SEARCH NON-BRAND':"sum",
1624
+ # 'DIGITAL PARTNERS':"sum",
1625
+ # 'AUDIO':"sum",
1626
+ # 'EMAIL':"sum"
1627
+ # }).reset_index()
1628
+
1629
+ # def get_month_name(month_number):
1630
+
1631
+ # months = ["January", "February", "March", "April", "May", "June",
1632
+ # "July", "August", "September", "October", "November", "December"]
1633
+ # if 1 <= month_number <= 12:
1634
+ # return months[month_number - 1]
1635
+ # else:
1636
+ # return "Invalid month number"
1637
+
1638
+ # data2["Month year"] = data2["Month"].apply(get_month_name) + ' ' +(data2["Date"].dt.year+1).astype(str)
1639
+ # # # # print(data2.columns)
1640
+ # data2 = data2[['Month year' ,'BROADCAST TV', 'CABLE TV',
1641
+ # 'CONNECTED & OTT TV', 'VIDEO', 'DISPLAY PROSPECTING',
1642
+ # 'DISPLAY RETARGETING', 'SOCIAL PROSPECTING', 'SOCIAL RETARGETING',
1643
+ # 'SEARCH BRAND', 'SEARCH NON-BRAND', 'DIGITAL PARTNERS', 'AUDIO',
1644
+ # 'EMAIL']]
1645
+ # data2.columns = ['Month ','BROADCAST TV', 'CABLE TV',
1646
+ # 'CONNECTED & OTT TV', 'VIDEO', 'DISPLAY PROSPECTING',
1647
+ # 'DISPLAY RETARGETING', 'SOCIAL PROSPECTING', 'SOCIAL RETARGETING',
1648
+ # 'SEARCH BRAND', 'SEARCH NON-BRAND', 'DIGITAL PARTNERS', 'AUDIO',
1649
+ # 'EMAIL']
1650
+
1651
+ # data2.set_index('Month ', inplace=True)
1652
+ # for c in ['BROADCAST TV', 'CABLE TV',
1653
+ # 'CONNECTED & OTT TV', 'VIDEO', 'DISPLAY PROSPECTING',
1654
+ # 'DISPLAY RETARGETING', 'SOCIAL PROSPECTING', 'SOCIAL RETARGETING',
1655
+ # 'SEARCH BRAND', 'SEARCH NON-BRAND', 'DIGITAL PARTNERS', 'AUDIO',
1656
+ # 'EMAIL']:
1657
+ # data2[c] = data2[c].apply(lambda x: "${:,.0f}".format(x))
1658
+ return key_df
1659
+
Test/X_test_tuned_trend.csv ADDED
@@ -0,0 +1,971 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ paid_search_clicks,kwai_clicks,fb_level_achieved_tier_2_clicks_lag_2,fb_level_achieved_tier_1_impressions,ga_app_clicks,digital_tactic_others_impressions_lag_2,programmatic_clicks_lag_3,total_approved_accounts_revenue,date,dma,Trend
2
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06194251734390485,31.746,8/7/2023,Albany/Schenectady/Troy SMM Food,124
3
+ 0.0,0.0010625686993517797,0.0,0.0,0.005135905343058742,0.0,0.0,30.66,8/8/2022,Albany/Schenectady/Troy SMM Food,125
4
+ 0.0,0.0,0.0,0.0,0.0019373305473274695,0.0,0.0,31.61,8/9/2021,Albany/Schenectady/Troy SMM Food,126
5
+ 0.0,0.0,0.006928265811381233,0.0,0.0,0.04710893906935569,0.062438057482656094,31.871,9/11/2023,Albany/Schenectady/Troy SMM Food,127
6
+ 0.0,0.0,0.0,0.013920804779456755,0.0,0.0,0.0,34.48,9/12/2022,Albany/Schenectady/Troy SMM Food,128
7
+ 0.0,0.0,0.0,0.0,0.0014406267064896794,0.0,0.0,34.3,9/13/2021,Albany/Schenectady/Troy SMM Food,129
8
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06442021803766104,38.922,9/18/2023,Albany/Schenectady/Troy SMM Food,130
9
+ 0.0,0.0,0.0,0.014511012797352662,0.0,0.0,0.0,34.78,9/19/2022,Albany/Schenectady/Troy SMM Food,131
10
+ 0.0,0.0,0.0,0.0,0.0010515523405034157,0.0,0.0,34.23,9/20/2021,Albany/Schenectady/Troy SMM Food,132
11
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06838453914767095,36.091,9/25/2023,Albany/Schenectady/Troy SMM Food,133
12
+ 0.0,0.0,0.0,0.016489078958499923,0.0,0.0,0.0,34.21,9/26/2022,Albany/Schenectady/Troy SMM Food,134
13
+ 0.0,0.0,0.0,0.0,0.0011647488571576068,0.0,0.0,33.64,9/27/2021,Albany/Schenectady/Troy SMM Food,135
14
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06045589692765114,31.809,9/4/2023,Albany/Schenectady/Troy SMM Food,136
15
+ 0.0,0.0,0.0,0.014564429905722917,0.0,0.0,0.0,30.83,9/5/2022,Albany/Schenectady/Troy SMM Food,137
16
+ 0.0,0.0,0.0,0.0,0.0016552670959924358,0.0,0.0,32.16,9/6/2021,Albany/Schenectady/Troy SMM Food,138
17
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06293359762140734,19.524,8/7/2023,Albuquerque/Santa FE SMM Food,124
18
+ 0.0,0.0011847395500790977,0.0,0.0,0.005197761363088355,0.0,0.0,17.41,8/8/2022,Albuquerque/Santa FE SMM Food,125
19
+ 0.0,0.0,0.0,0.0,0.0011734086999617528,0.0,0.0,20.25,8/9/2021,Albuquerque/Santa FE SMM Food,126
20
+ 0.0,0.0,0.006270420242227,0.0,0.0,0.05228225082270357,0.06045589692765114,20.598,9/11/2023,Albuquerque/Santa FE SMM Food,127
21
+ 0.0,0.0,0.0,0.013504398628886482,0.0,0.0,0.0,18.96,9/12/2022,Albuquerque/Santa FE SMM Food,128
22
+ 0.0,0.0,0.0,0.0,0.0015389777783367637,0.0,0.0,22.17,9/13/2021,Albuquerque/Santa FE SMM Food,129
23
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05252725470763132,20.817,9/18/2023,Albuquerque/Santa FE SMM Food,130
24
+ 0.0,0.0,0.0,0.014076952049886973,0.0,0.0,0.0,19.46,9/19/2022,Albuquerque/Santa FE SMM Food,131
25
+ 0.0,0.0,0.0,0.0,0.0015210395325281761,0.0,0.0,21.48,9/20/2021,Albuquerque/Santa FE SMM Food,132
26
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.051040634291377604,19.984,9/25/2023,Albuquerque/Santa FE SMM Food,133
27
+ 0.0,0.0,0.0,0.015995849296932277,0.0,0.0,0.0,21.41,9/26/2022,Albuquerque/Santa FE SMM Food,134
28
+ 0.0,0.0,0.0,0.0,0.0009569126298581084,0.0,0.0,20.66,9/27/2021,Albuquerque/Santa FE SMM Food,135
29
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05153617443012884,19.474,9/4/2023,Albuquerque/Santa FE SMM Food,136
30
+ 0.0,0.0,0.0,0.014128771317940983,0.0,0.0,0.0,18.86,9/5/2022,Albuquerque/Santa FE SMM Food,137
31
+ 0.0,0.0,0.0,0.0,0.0009513455880554432,0.0,0.0,22.19,9/6/2021,Albuquerque/Santa FE SMM Food,138
32
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.211595639246779,261.197,8/7/2023,Atlanta SMM Food,124
33
+ 0.0,0.008222704775902465,0.0,0.0,0.020853520032583325,0.0,0.0,156.16,8/8/2022,Atlanta SMM Food,125
34
+ 0.0,0.0,0.0,0.0,0.004707243124253526,0.0,0.0,101.3,8/9/2021,Atlanta SMM Food,126
35
+ 0.0,0.0,0.07059033189111122,0.0,0.0,0.25431693894538904,0.1952428146679881,140.383,9/11/2023,Atlanta SMM Food,127
36
+ 0.0,0.0,0.0,0.05367166201076247,0.0,0.0,0.0,112.47,9/12/2022,Atlanta SMM Food,128
37
+ 0.0,0.0,0.0,0.0,0.0042668282616426835,0.0,0.0,110.36,9/13/2021,Atlanta SMM Food,129
38
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20069375619425173,132.639,9/18/2023,Atlanta SMM Food,130
39
+ 0.0,0.0,0.0,0.05594720898632875,0.0,0.0,0.0,106.1,9/19/2022,Atlanta SMM Food,131
40
+ 0.0,0.0,0.0,0.0,0.004526623545767057,0.0,0.0,122.59,9/20/2021,Atlanta SMM Food,132
41
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17195242814667988,131.807,9/25/2023,Atlanta SMM Food,133
42
+ 0.0,0.0,0.0,0.06357364295489033,0.0,0.0,0.0,117.87,9/26/2022,Atlanta SMM Food,134
43
+ 0.0,0.0,0.0,0.0,0.0025589835486250767,0.0,0.0,116.38,9/27/2021,Atlanta SMM Food,135
44
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.19127849355797819,138.316,9/4/2023,Atlanta SMM Food,136
45
+ 0.0,0.0,0.0,0.05615315864933586,0.0,0.0,0.0,101.43,9/5/2022,Atlanta SMM Food,137
46
+ 0.0,0.0,0.0,0.0,0.005283741230929517,0.0,0.0,109.49,9/6/2021,Atlanta SMM Food,138
47
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08969276511397423,50.534,8/7/2023,Baltimore SMM Food,124
48
+ 0.0,0.003010948271471134,0.0,0.0,0.010581709346465842,0.0,0.0,54.66,8/8/2022,Baltimore SMM Food,125
49
+ 0.0,0.0,0.0,0.0,0.002178569025442959,0.0,0.0,54.51,8/9/2021,Baltimore SMM Food,126
50
+ 0.0,0.0,0.013868768647461295,0.0,0.0,0.09580695439115328,0.06987115956392467,63.01,9/11/2023,Baltimore SMM Food,127
51
+ 0.0,0.0,0.0,0.02379803605790658,0.0,0.0,0.0,58.19,9/12/2022,Baltimore SMM Food,128
52
+ 0.0,0.0,0.0,0.0,0.002276920097290043,0.0,0.0,61.67,9/13/2021,Baltimore SMM Food,129
53
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06442021803766104,72.253,9/18/2023,Baltimore SMM Food,130
54
+ 0.0,0.0,0.0,0.024807014486139218,0.0,0.0,0.0,60.84,9/19/2022,Baltimore SMM Food,131
55
+ 0.0,0.0,0.0,0.0,0.001681865184605169,0.0,0.0,56.75,9/20/2021,Baltimore SMM Food,132
56
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07383548067393458,74.369,9/25/2023,Baltimore SMM Food,133
57
+ 0.0,0.0,0.0,0.028188578310361815,0.0,0.0,0.0,63.62,9/26/2022,Baltimore SMM Food,134
58
+ 0.0,0.0,0.0,0.0,0.0016020709187669687,0.0,0.0,55.3,9/27/2021,Baltimore SMM Food,135
59
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07433102081268583,56.708,9/4/2023,Baltimore SMM Food,136
60
+ 0.0,0.0,0.0,0.024898332642610616,0.0,0.0,0.0,57.06,9/5/2022,Baltimore SMM Food,137
61
+ 0.0,0.0,0.0,0.0,0.0019039282965114788,0.0,0.0,64.56,9/6/2021,Baltimore SMM Food,138
62
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.028245787908820614,2.491,8/7/2023,Baton Rouge SMM Food,124
63
+ 0.0,0.0005060126015939978,0.0,0.0,0.0027847580217331635,0.0,0.0,2.29,8/8/2022,Baton Rouge SMM Food,125
64
+ 0.0,0.0,0.0,0.0,0.0007769116115719355,0.0,0.0,2.82,8/9/2021,Baton Rouge SMM Food,126
65
+ 0.0,0.0,0.0026347580075683306,0.0,0.0,0.0372315586355452,0.019821605550049554,3.282,9/11/2023,Baton Rouge SMM Food,127
66
+ 0.0,0.0,0.0,0.009473010003288533,0.0,0.0,0.0,2.93,9/12/2022,Baton Rouge SMM Food,128
67
+ 0.0,0.0,0.0,0.0,0.000550518578263553,0.0,0.0,6.28,9/13/2021,Baton Rouge SMM Food,129
68
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.027254707631318136,3.751,9/18/2023,Baton Rouge SMM Food,130
69
+ 0.0,0.0,0.0,0.009874642417058198,0.0,0.0,0.0,1.6,9/19/2022,Baton Rouge SMM Food,131
70
+ 0.0,0.0,0.0,0.0,0.0007249525547470607,0.0,0.0,3.84,9/20/2021,Baton Rouge SMM Food,132
71
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.020317145688800792,2.883,9/25/2023,Baton Rouge SMM Food,133
72
+ 0.0,0.0,0.0,0.01122070256617374,0.0,0.0,0.0,1.98,9/26/2022,Baton Rouge SMM Food,134
73
+ 0.0,0.0,0.0,0.0,0.0005325803324549652,0.0,0.0,2.19,9/27/2021,Baton Rouge SMM Food,135
74
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.02081268582755203,5.023,9/4/2023,Baton Rouge SMM Food,136
75
+ 0.0,0.0,0.0,0.009910992383390915,0.0,0.0,0.0,3.56,9/5/2022,Baton Rouge SMM Food,137
76
+ 0.0,0.0,0.0,0.0,0.000716911272143211,0.0,0.0,2.76,9/6/2021,Baton Rouge SMM Food,138
77
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07086223984142716,30.899,8/7/2023,Birmingham/Anniston/Tuscaloosa SMM Food,124
78
+ 0.0,0.0015968856587974965,0.0,0.0,0.006559212363940131,0.0,0.0,21.32,8/8/2022,Birmingham/Anniston/Tuscaloosa SMM Food,125
79
+ 0.0,0.0,0.0,0.0,0.002610324045249656,0.0,0.0,12.39,8/9/2021,Birmingham/Anniston/Tuscaloosa SMM Food,126
80
+ 0.0,0.0,0.011830671085553057,0.0,0.0,0.06832539296539691,0.05302279484638256,11.227,9/11/2023,Birmingham/Anniston/Tuscaloosa SMM Food,127
81
+ 0.0,0.0,0.0,0.020386457479869002,0.0,0.0,0.0,11.48,9/12/2022,Birmingham/Anniston/Tuscaloosa SMM Food,128
82
+ 0.0,0.0,0.0,0.0,0.0017505253668380393,0.0,0.0,12.29,9/13/2021,Birmingham/Anniston/Tuscaloosa SMM Food,129
83
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06095143706640238,11.018,9/18/2023,Birmingham/Anniston/Tuscaloosa SMM Food,130
84
+ 0.0,0.0,0.0,0.021250793330832705,0.0,0.0,0.0,9.71,9/19/2022,Birmingham/Anniston/Tuscaloosa SMM Food,131
85
+ 0.0,0.0,0.0,0.0,0.002048671383380772,0.0,0.0,12.55,9/20/2021,Birmingham/Anniston/Tuscaloosa SMM Food,132
86
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.055996035678889985,9.499,9/25/2023,Birmingham/Anniston/Tuscaloosa SMM Food,133
87
+ 0.0,0.0,0.0,0.02414759149407838,0.0,0.0,0.0,9.26,9/26/2022,Birmingham/Anniston/Tuscaloosa SMM Food,134
88
+ 0.0,0.0,0.0,0.0,0.001227223437387516,0.0,0.0,11.65,9/27/2021,Birmingham/Anniston/Tuscaloosa SMM Food,135
89
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.051040634291377604,14.16,9/4/2023,Birmingham/Anniston/Tuscaloosa SMM Food,136
90
+ 0.0,0.0,0.0,0.021329020533966504,0.0,0.0,0.0,13.7,9/5/2022,Birmingham/Anniston/Tuscaloosa SMM Food,137
91
+ 0.0,0.0,0.0,0.0,0.001038562576297197,0.0,0.0,12.02,9/6/2021,Birmingham/Anniston/Tuscaloosa SMM Food,138
92
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20416253716551042,142.058,8/7/2023,Boston/Manchester SMM Food,124
93
+ 0.0,0.006427977432121013,0.0,0.0,0.02215311501340549,0.0,0.0,133.68,8/8/2022,Boston/Manchester SMM Food,125
94
+ 0.0,0.0,0.0,0.0,0.006543129798732431,0.0,0.0,118.91,8/9/2021,Boston/Manchester SMM Food,126
95
+ 0.0,0.0,0.04895274042536989,0.0,0.0,0.16361847104901653,0.1798810703666997,172.275,9/11/2023,Boston/Manchester SMM Food,127
96
+ 0.0,0.0,0.0,0.06149452980004475,0.0,0.0,0.0,167.04,9/12/2022,Boston/Manchester SMM Food,128
97
+ 0.0,0.0,0.0,0.0,0.0038660012518507932,0.0,0.0,117.31,9/13/2021,Boston/Manchester SMM Food,129
98
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.19425173439048563,178.545,9/18/2023,Boston/Manchester SMM Food,130
99
+ 0.0,0.0,0.0,0.06410174720660182,0.0,0.0,0.0,145.96,9/19/2022,Boston/Manchester SMM Food,131
100
+ 0.0,0.0,0.0,0.0,0.0032907402655753953,0.0,0.0,113.79,9/20/2021,Boston/Manchester SMM Food,132
101
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.22398414271555994,156.549,9/25/2023,Boston/Manchester SMM Food,133
102
+ 0.0,0.0,0.0,0.07283976560910188,0.0,0.0,0.0,157.5,9/26/2022,Boston/Manchester SMM Food,134
103
+ 0.0,0.0,0.0,0.0,0.0044307467147211566,0.0,0.0,114.52,9/27/2021,Boston/Manchester SMM Food,135
104
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.19573835480673935,149.121,9/4/2023,Boston/Manchester SMM Food,136
105
+ 0.0,0.0,0.0,0.06433771488842611,0.0,0.0,0.0,138.78,9/5/2022,Boston/Manchester SMM Food,137
106
+ 0.0,0.0,0.0,0.0,0.004624356057413845,0.0,0.0,116.39,9/6/2021,Boston/Manchester SMM Food,138
107
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07036669970267592,21.059,8/7/2023,Buffalo SMM Food,124
108
+ 0.0,0.001065745719110646,0.0,0.0,0.006125601663532545,0.0,0.0,14.52,8/8/2022,Buffalo SMM Food,125
109
+ 0.0,0.0,0.0,0.0,0.002417333262757264,0.0,0.0,16.9,8/9/2021,Buffalo SMM Food,126
110
+ 0.0,0.0,0.007447706411528032,0.0,0.0,0.05334496751978329,0.06987115956392467,21.384,9/11/2023,Buffalo SMM Food,127
111
+ 0.0,0.0,0.0,0.016659126610822184,0.0,0.0,0.0,16.16,9/12/2022,Buffalo SMM Food,128
112
+ 0.0,0.0,0.0,0.0,0.0018525877998869001,0.0,0.0,17.94,9/13/2021,Buffalo SMM Food,129
113
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07333994053518335,19.469,9/18/2023,Buffalo SMM Food,130
114
+ 0.0,0.0,0.0,0.017365432764953035,0.0,0.0,0.0,15.79,9/19/2022,Buffalo SMM Food,131
115
+ 0.0,0.0,0.0,0.0,0.0014635134339006364,0.0,0.0,13.96,9/20/2021,Buffalo SMM Food,132
116
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07284440039643211,19.007,9/25/2023,Buffalo SMM Food,133
117
+ 0.0,0.0,0.0,0.019732598682000637,0.0,0.0,0.0,17.25,9/26/2022,Buffalo SMM Food,134
118
+ 0.0,0.0,0.0,0.0,0.0011474291715493155,0.0,0.0,16.09,9/27/2021,Buffalo SMM Food,135
119
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05698711595639247,24.686,9/4/2023,Buffalo SMM Food,136
120
+ 0.0,0.0,0.0,0.01742935740030342,0.0,0.0,0.0,24.05,9/5/2022,Buffalo SMM Food,137
121
+ 0.0,0.0,0.0,0.0,0.002140218293024599,0.0,0.0,18.49,9/6/2021,Buffalo SMM Food,138
122
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11248761149653122,91.731,8/7/2023,Charlotte SMM Food,124
123
+ 0.0,0.00275216557111256,0.0,0.0,0.01447925716853174,0.0,0.0,105.22,8/8/2022,Charlotte SMM Food,125
124
+ 0.0,0.0,0.0,0.0,0.00312867749309781,0.0,0.0,68.53,8/9/2021,Charlotte SMM Food,126
125
+ 0.0,0.0,0.019428597524418424,0.0,0.0,0.14467607804531682,0.10257680872150644,109.118,9/11/2023,Charlotte SMM Food,127
126
+ 0.0,0.0,0.0,0.0334917711067763,0.0,0.0,0.0,90.2,9/12/2022,Charlotte SMM Food,128
127
+ 0.0,0.0,0.0,0.0,0.0033154826735872405,0.0,0.0,71.22,9/13/2021,Charlotte SMM Food,129
128
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09712586719524281,95.013,9/18/2023,Charlotte SMM Food,130
129
+ 0.0,0.0,0.0,0.03491174014852976,0.0,0.0,0.0,80.4,9/19/2022,Charlotte SMM Food,131
130
+ 0.0,0.0,0.0,0.0,0.0025410453028164894,0.0,0.0,67.35,9/20/2021,Charlotte SMM Food,132
131
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10009910802775024,115.348,9/25/2023,Charlotte SMM Food,133
132
+ 0.0,0.0,0.0,0.03967072787903239,0.0,0.0,0.0,69.61,9/26/2022,Charlotte SMM Food,134
133
+ 0.0,0.0,0.0,0.0,0.0018940313333067407,0.0,0.0,67.22,9/27/2021,Charlotte SMM Food,135
134
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09514370664023786,64.194,9/4/2023,Charlotte SMM Food,136
135
+ 0.0,0.0,0.0,0.035040255247413665,0.0,0.0,0.0,69.04,9/5/2022,Charlotte SMM Food,137
136
+ 0.0,0.0,0.0,0.0,0.0029257897474006802,0.0,0.0,95.05,9/6/2021,Charlotte SMM Food,138
137
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2259663032705649,127.164,8/7/2023,Chicago SMM Food,124
138
+ 0.0,0.021210939190104566,0.0,0.0,0.029393362157871656,0.0,0.0,128.34,8/8/2022,Chicago SMM Food,125
139
+ 0.0,0.0,0.0,0.0,0.007107256701402499,0.0,0.0,131.14,8/9/2021,Chicago SMM Food,126
140
+ 0.0,0.0,0.15988812078214787,0.0,0.0,0.2559436219550531,0.21110009910802774,139.546,9/11/2023,Chicago SMM Food,127
141
+ 0.0,0.0,0.0,0.07186262484115848,0.0,0.0,0.0,115.04,9/12/2022,Chicago SMM Food,128
142
+ 0.0,0.0,0.0,0.0,0.004144971902184347,0.0,0.0,126.47,9/13/2021,Chicago SMM Food,129
143
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2423191278493558,150.534,9/18/2023,Chicago SMM Food,130
144
+ 0.0,0.0,0.0,0.07490942409399909,0.0,0.0,0.0,112.06,9/19/2022,Chicago SMM Food,131
145
+ 0.0,0.0,0.0,0.0,0.004689304878444938,0.0,0.0,105.95,9/20/2021,Chicago SMM Food,132
146
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17443012884043607,140.18,9/25/2023,Chicago SMM Food,133
147
+ 0.0,0.0,0.0,0.0851206890876872,0.0,0.0,0.0,113.37,9/26/2022,Chicago SMM Food,134
148
+ 0.0,0.0,0.0,0.0,0.005144565185862888,0.0,0.0,112.47,9/27/2021,Chicago SMM Food,135
149
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17938553022794845,134.87,9/4/2023,Chicago SMM Food,136
150
+ 0.0,0.0,0.0,0.07518517635856978,0.0,0.0,0.0,128.32,9/5/2022,Chicago SMM Food,137
151
+ 0.0,0.0,0.0,0.0,0.005288071152331588,0.0,0.0,132.52,9/6/2021,Chicago SMM Food,138
152
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1442021803766105,72.288,8/7/2023,Cleveland/Akron/Canton SMM Food,124
153
+ 0.0,0.0,0.0,0.0,0.010643565366495456,0.0,0.0,88.44,8/8/2022,Cleveland/Akron/Canton SMM Food,125
154
+ 0.0,0.0,0.0,0.0,0.005229307933303457,0.0,0.0,81.13,8/9/2021,Cleveland/Akron/Canton SMM Food,126
155
+ 0.0,0.0,0.018360600644668993,0.0,0.0,0.003847068303229848,0.13082259663032705,77.361,9/11/2023,Cleveland/Akron/Canton SMM Food,127
156
+ 0.0,0.0,0.0,0.04319655098784653,0.0,0.0,0.0,83.99,9/12/2022,Cleveland/Akron/Canton SMM Food,128
157
+ 0.0,0.0,0.0,0.0,0.0038678569324516817,0.0,0.0,81.0,9/13/2021,Cleveland/Akron/Canton SMM Food,129
158
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1367690782953419,74.588,9/18/2023,Cleveland/Akron/Canton SMM Food,130
159
+ 0.0,0.0,0.0,0.045027978918762056,0.0,0.0,0.0,68.98,9/19/2022,Cleveland/Akron/Canton SMM Food,131
160
+ 0.0,0.0,0.0,0.0,0.004016929940723048,0.0,0.0,79.08,9/20/2021,Cleveland/Akron/Canton SMM Food,132
161
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1337958374628345,75.304,9/25/2023,Cleveland/Akron/Canton SMM Food,133
162
+ 0.0,0.0,0.0,0.05116595995981537,0.0,0.0,0.0,73.72,9/26/2022,Cleveland/Akron/Canton SMM Food,134
163
+ 0.0,0.0,0.0,0.0,0.003246203931154074,0.0,0.0,72.7,9/27/2021,Cleveland/Akron/Canton SMM Food,135
164
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12983151635282458,85.988,9/4/2023,Cleveland/Akron/Canton SMM Food,136
165
+ 0.0,0.0,0.0,0.04519373333208909,0.0,0.0,0.0,95.79,9/5/2022,Cleveland/Akron/Canton SMM Food,137
166
+ 0.0,0.0,0.0,0.0,0.0032332141669478556,0.0,0.0,84.14,9/6/2021,Cleveland/Akron/Canton SMM Food,138
167
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10555004955401387,54.72,8/7/2023,Columbus OH SMM Food,124
168
+ 0.0,0.0016355875358600512,0.0,0.0,0.010457378746206322,0.0,0.0,58.12,8/8/2022,Columbus OH SMM Food,125
169
+ 0.0,0.0,0.0,0.0,0.003066821473068197,0.0,0.0,54.05,8/9/2021,Columbus OH SMM Food,126
170
+ 0.0,0.0,0.012976309777184706,0.0,0.0,0.09535695517348619,0.09563924677898909,56.575,9/11/2023,Columbus OH SMM Food,127
171
+ 0.0,0.0,0.0,0.026403905702080413,0.0,0.0,0.0,54.07,9/12/2022,Columbus OH SMM Food,128
172
+ 0.0,0.0,0.0,0.0,0.002041867221177515,0.0,0.0,53.22,9/13/2021,Columbus OH SMM Food,129
173
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0931615460852329,59.875,9/18/2023,Columbus OH SMM Food,130
174
+ 0.0,0.0,0.0,0.0275233666153899,0.0,0.0,0.0,51.71,9/19/2022,Columbus OH SMM Food,131
175
+ 0.0,0.0,0.0,0.0,0.0023913537343448264,0.0,0.0,47.83,9/20/2021,Columbus OH SMM Food,132
176
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0753221010901883,61.444,9/25/2023,Columbus OH SMM Food,133
177
+ 0.0,0.0,0.0,0.031275209501753144,0.0,0.0,0.0,56.01,9/26/2022,Columbus OH SMM Food,134
178
+ 0.0,0.0,0.0,0.0,0.0023177450705095877,0.0,0.0,51.58,9/27/2021,Columbus OH SMM Food,135
179
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0817641228939544,60.308,9/4/2023,Columbus OH SMM Food,136
180
+ 0.0,0.0,0.0,0.027624684053467907,0.0,0.0,0.0,61.28,9/5/2022,Columbus OH SMM Food,137
181
+ 0.0,0.0,0.0,0.0,0.0019162995005174012,0.0,0.0,56.04,9/6/2021,Columbus OH SMM Food,138
182
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.22150644202180375,73.064,8/7/2023,Dallas/Ft. Worth SMM Food,124
183
+ 0.0,0.007823266746219531,0.0,0.0,0.02227744561366501,0.0,0.0,55.67,8/8/2022,Dallas/Ft. Worth SMM Food,125
184
+ 0.0,0.0,0.0,0.0,0.00542044303519496,0.0,0.0,58.56,8/9/2021,Dallas/Ft. Worth SMM Food,126
185
+ 0.0,0.0,0.053580445593371474,0.0,0.0,0.2960835671223029,0.20366699702675917,82.586,9/11/2023,Dallas/Ft. Worth SMM Food,127
186
+ 0.0,0.0,0.0,0.055526458478242974,0.0,0.0,0.0,62.13,9/12/2022,Dallas/Ft. Worth SMM Food,128
187
+ 0.0,0.0,0.0,0.0,0.004551365953778902,0.0,0.0,54.28,9/13/2021,Dallas/Ft. Worth SMM Food,129
188
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20862239841427155,77.309,9/18/2023,Dallas/Ft. Worth SMM Food,130
189
+ 0.0,0.0,0.0,0.05788064427948714,0.0,0.0,0.0,58.16,9/19/2022,Dallas/Ft. Worth SMM Food,131
190
+ 0.0,0.0,0.0,0.0,0.005119822777851043,0.0,0.0,55.82,9/20/2021,Dallas/Ft. Worth SMM Food,132
191
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.21258671952428146,75.709,9/25/2023,Dallas/Ft. Worth SMM Food,133
192
+ 0.0,0.0,0.0,0.06577063414997705,0.0,0.0,0.0,62.33,9/26/2022,Dallas/Ft. Worth SMM Food,134
193
+ 0.0,0.0,0.0,0.0,0.003531360183490589,0.0,0.0,56.4,9/27/2021,Dallas/Ft. Worth SMM Food,135
194
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1734390485629336,80.36,9/4/2023,Dallas/Ft. Worth SMM Food,136
195
+ 0.0,0.0,0.0,0.058093711196037776,0.0,0.0,0.0,60.65,9/5/2022,Dallas/Ft. Worth SMM Food,137
196
+ 0.0,0.0,0.0,0.0,0.004822913881708902,0.0,0.0,60.16,9/6/2021,Dallas/Ft. Worth SMM Food,138
197
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06095143706640238,19.057,8/7/2023,Des Moines/Ames SMM Food,124
198
+ 0.0,0.001062279879373701,0.0,0.0,0.002908470061792389,0.0,0.0,21.69,8/8/2022,Des Moines/Ames SMM Food,125
199
+ 0.0,0.0,0.0,0.0,0.0009030978924323453,0.0,0.0,15.48,8/9/2021,Des Moines/Ames SMM Food,126
200
+ 0.0,0.0,0.007034601336350359,0.0,0.0,0.038076904404842446,0.0639246778989098,17.536,9/11/2023,Des Moines/Ames SMM Food,127
201
+ 0.0,0.0,0.0,0.009818746375673355,0.0,0.0,0.0,19.26,9/12/2022,Des Moines/Ames SMM Food,128
202
+ 0.0,0.0,0.0,0.0,0.0007459836015571291,0.0,0.0,16.86,9/13/2021,Des Moines/Ames SMM Food,129
203
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05401387512388503,19.413,9/18/2023,Des Moines/Ames SMM Food,130
204
+ 0.0,0.0,0.0,0.010235037169468615,0.0,0.0,0.0,17.91,9/19/2022,Des Moines/Ames SMM Food,131
205
+ 0.0,0.0,0.0,0.0,0.0005560856200662181,0.0,0.0,16.58,9/20/2021,Des Moines/Ames SMM Food,132
206
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05797819623389494,20.201,9/25/2023,Des Moines/Ames SMM Food,133
207
+ 0.0,0.0,0.0,0.011630224459597573,0.0,0.0,0.0,17.11,9/26/2022,Des Moines/Ames SMM Food,134
208
+ 0.0,0.0,0.0,0.0,0.000921036138240933,0.0,0.0,12.87,9/27/2021,Des Moines/Ames SMM Food,135
209
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04707631318136769,20.614,9/4/2023,Des Moines/Ames SMM Food,136
210
+ 0.0,0.0,0.0,0.010272713801757724,0.0,0.0,0.0,19.45,9/5/2022,Des Moines/Ames SMM Food,137
211
+ 0.0,0.0,0.0,0.0,0.0008585615580110242,0.0,0.0,16.73,9/6/2021,Des Moines/Ames SMM Food,138
212
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14073339940535184,124.957,8/7/2023,Detroit SMM Food,124
213
+ 0.0,0.004029038694198784,0.0,0.0,0.01633679345002101,0.0,0.0,129.16,8/8/2022,Detroit SMM Food,125
214
+ 0.0,0.0,0.0,0.0,0.005138998144060223,0.0,0.0,98.0,8/9/2021,Detroit SMM Food,126
215
+ 0.0,0.0,0.027197842309067383,0.0,0.0,0.16679364832597332,0.1367690782953419,114.674,9/11/2023,Detroit SMM Food,127
216
+ 0.0,0.0,0.0,0.05264923653159416,0.0,0.0,0.0,99.78,9/12/2022,Detroit SMM Food,128
217
+ 0.0,0.0,0.0,0.0,0.003737959290389495,0.0,0.0,105.22,9/13/2021,Detroit SMM Food,129
218
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13478691774033696,132.01,9/18/2023,Detroit SMM Food,130
219
+ 0.0,0.0,0.0,0.05488143517450875,0.0,0.0,0.0,98.35,9/19/2022,Detroit SMM Food,131
220
+ 0.0,0.0,0.0,0.0,0.004616314774809995,0.0,0.0,76.97,9/20/2021,Detroit SMM Food,132
221
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12041625371655104,134.155,9/25/2023,Detroit SMM Food,133
222
+ 0.0,0.0,0.0,0.062362588370685694,0.0,0.0,0.0,111.04,9/26/2022,Detroit SMM Food,134
223
+ 0.0,0.0,0.0,0.0,0.004344766846879995,0.0,0.0,88.84,9/27/2021,Detroit SMM Food,135
224
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11397423191278494,147.194,9/4/2023,Detroit SMM Food,136
225
+ 0.0,0.0,0.0,0.05508346156574187,0.0,0.0,0.0,125.93,9/5/2022,Detroit SMM Food,137
226
+ 0.0,0.0,0.0,0.0,0.00365569078375011,0.0,0.0,109.54,9/6/2021,Detroit SMM Food,138
227
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09365708622398414,71.874,8/7/2023,Grand Rapids SMM Food,124
228
+ 0.0,0.0,0.0,0.0,0.008291799484969583,0.0,0.0,89.36,8/8/2022,Grand Rapids SMM Food,125
229
+ 0.0,0.0,0.0,0.0,0.0016558856561927318,0.0,0.0,60.59,8/9/2021,Grand Rapids SMM Food,126
230
+ 0.0,0.0,0.010334378341344649,0.0,0.0,0.004593258733825526,0.06937561942517344,59.484,9/11/2023,Grand Rapids SMM Food,127
231
+ 0.0,0.0,0.0,0.022162738793584366,0.0,0.0,0.0,51.84,9/12/2022,Grand Rapids SMM Food,128
232
+ 0.0,0.0,0.0,0.0,0.0015989781177654881,0.0,0.0,62.76,9/13/2021,Grand Rapids SMM Food,129
233
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10852329038652131,84.959,9/18/2023,Grand Rapids SMM Food,130
234
+ 0.0,0.0,0.0,0.023102384621302353,0.0,0.0,0.0,53.77,9/19/2022,Grand Rapids SMM Food,131
235
+ 0.0,0.0,0.0,0.0,0.001827226831674759,0.0,0.0,45.22,9/20/2021,Grand Rapids SMM Food,132
236
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08572844400396432,79.122,9/25/2023,Grand Rapids SMM Food,133
237
+ 0.0,0.0,0.0,0.02625158212085696,0.0,0.0,0.0,53.48,9/26/2022,Grand Rapids SMM Food,134
238
+ 0.0,0.0,0.0,0.0,0.0012488730443978803,0.0,0.0,45.61,9/27/2021,Grand Rapids SMM Food,135
239
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06689791873141725,97.272,9/4/2023,Grand Rapids SMM Food,136
240
+ 0.0,0.0,0.0,0.023187427795256017,0.0,0.0,0.0,79.71,9/5/2022,Grand Rapids SMM Food,137
241
+ 0.0,0.0,0.0,0.0,0.001495678564316035,0.0,0.0,69.21,9/6/2021,Grand Rapids SMM Food,138
242
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05847373637264618,34.23,8/7/2023,Greensboro SMM Food,124
243
+ 0.0,0.0,0.0,0.0,0.008662935605147259,0.0,0.0,41.28,8/8/2022,Greensboro SMM Food,125
244
+ 0.0,0.0,0.0,0.0,0.002148878135828745,0.0,0.0,33.05,8/9/2021,Greensboro SMM Food,126
245
+ 0.0,0.0,0.0,0.0,0.0,0.004162733342605559,0.05302279484638256,40.267,9/11/2023,Greensboro SMM Food,127
246
+ 0.0,0.0,0.0,0.01938722492394592,0.0,0.0,0.0,38.46,9/12/2022,Greensboro SMM Food,128
247
+ 0.0,0.0,0.0,0.0,0.0019855782429505676,0.0,0.0,34.42,9/13/2021,Greensboro SMM Food,129
248
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.059960356788899896,39.972,9/18/2023,Greensboro SMM Food,130
249
+ 0.0,0.0,0.0,0.02020919576536063,0.0,0.0,0.0,37.05,9/19/2022,Greensboro SMM Food,131
250
+ 0.0,0.0,0.0,0.0,0.0019132066995159206,0.0,0.0,29.9,9/20/2021,Greensboro SMM Food,132
251
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05698711595639247,58.21,9/25/2023,Greensboro SMM Food,133
252
+ 0.0,0.0,0.0,0.022964008737958168,0.0,0.0,0.0,31.18,9/26/2022,Greensboro SMM Food,134
253
+ 0.0,0.0,0.0,0.0,0.0017647522514448503,0.0,0.0,32.39,9/27/2021,Greensboro SMM Food,135
254
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05004955401387512,28.032,9/4/2023,Greensboro SMM Food,136
255
+ 0.0,0.0,0.0,0.020283588694575232,0.0,0.0,0.0,31.02,9/5/2022,Greensboro SMM Food,137
256
+ 0.0,0.0,0.0,0.0,0.0016861951060072422,0.0,0.0,55.3,9/6/2021,Greensboro SMM Food,138
257
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08622398414271557,34.307,8/7/2023,Harrisburg/Lancaster SMM Food,124
258
+ 0.0,0.00118647246994757,0.0,0.0,0.010951608346242928,0.0,0.0,37.54,8/8/2022,Harrisburg/Lancaster SMM Food,125
259
+ 0.0,0.0,0.0,0.0,0.0027989849063399744,0.0,0.0,31.88,8/9/2021,Harrisburg/Lancaster SMM Food,126
260
+ 0.0,0.0,0.009303514502060626,0.0,0.0,0.05938927543516645,0.06838453914767095,47.335,9/11/2023,Harrisburg/Lancaster SMM Food,127
261
+ 0.0,0.0,0.0,0.01722270730805324,0.0,0.0,0.0,47.54,9/12/2022,Harrisburg/Lancaster SMM Food,128
262
+ 0.0,0.0,0.0,0.0,0.0017567109688410004,0.0,0.0,37.65,9/13/2021,Harrisburg/Lancaster SMM Food,129
263
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06838453914767095,47.204,9/18/2023,Harrisburg/Lancaster SMM Food,130
264
+ 0.0,0.0,0.0,0.017952907903006455,0.0,0.0,0.0,47.12,9/19/2022,Harrisburg/Lancaster SMM Food,131
265
+ 0.0,0.0,0.0,0.0,0.0023622814049309086,0.0,0.0,39.6,9/20/2021,Harrisburg/Lancaster SMM Food,132
266
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06689791873141725,42.773,9/25/2023,Harrisburg/Lancaster SMM Food,133
267
+ 0.0,0.0,0.0,0.02040015539180732,0.0,0.0,0.0,39.34,9/26/2022,Harrisburg/Lancaster SMM Food,134
268
+ 0.0,0.0,0.0,0.0,0.0015365035375355792,0.0,0.0,36.2,9/27/2021,Harrisburg/Lancaster SMM Food,135
269
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06987115956392467,49.172,9/4/2023,Harrisburg/Lancaster SMM Food,136
270
+ 0.0,0.0,0.0,0.018018995117875386,0.0,0.0,0.0,46.11,9/5/2022,Harrisburg/Lancaster SMM Food,137
271
+ 0.0,0.0,0.0,0.0,0.0018253711510738705,0.0,0.0,41.15,9/6/2021,Harrisburg/Lancaster SMM Food,138
272
+ 0.0,0.0018337180408220845,0.0,0.0,0.010148098646058258,0.0,0.0,57.79,8/8/2022,Hartford/New Haven SMM Food,125
273
+ 0.0,0.0,0.0,0.0,0.0037509490545957138,0.0,0.0,69.72,8/9/2021,Hartford/New Haven SMM Food,126
274
+ 0.0,0.0,0.014994996886122389,0.0,0.0,0.08363767112400147,0.0882061446977205,74.813,9/11/2023,Hartford/New Haven SMM Food,127
275
+ 0.0,0.0,0.0,0.025926611998646588,0.0,0.0,0.0,80.45,9/12/2022,Hartford/New Haven SMM Food,128
276
+ 0.0,0.0,0.0,0.0,0.0030495017874599055,0.0,0.0,68.05,9/13/2021,Hartford/New Haven SMM Food,129
277
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10059464816650149,103.87,9/18/2023,Hartford/New Haven SMM Food,130
278
+ 0.0,0.0,0.0,0.027025836833104906,0.0,0.0,0.0,76.63,9/19/2022,Hartford/New Haven SMM Food,131
279
+ 0.0,0.0,0.0,0.0,0.0023901166139442343,0.0,0.0,59.62,9/20/2021,Hartford/New Haven SMM Food,132
280
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08721506442021804,89.9,9/25/2023,Hartford/New Haven SMM Food,133
281
+ 0.0,0.0,0.0,0.030709859033967845,0.0,0.0,0.0,79.63,9/26/2022,Hartford/New Haven SMM Food,134
282
+ 0.0,0.0,0.0,0.0,0.0023709412477350544,0.0,0.0,64.74,9/27/2021,Hartford/New Haven SMM Food,135
283
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09910802775024777,67.473,9/4/2023,Hartford/New Haven SMM Food,136
284
+ 0.0,0.0,0.0,0.027125322790759788,0.0,0.0,0.0,68.92,9/5/2022,Hartford/New Haven SMM Food,137
285
+ 0.0,0.0,0.0,0.0,0.0025515608262215235,0.0,0.0,67.33,9/6/2021,Hartford/New Haven SMM Food,138
286
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1962338949454906,133.105,8/7/2023,Houston SMM Food,124
287
+ 0.0,0.0046540451267612325,0.0,0.0,0.022832912673530933,0.0,0.0,118.76,8/8/2022,Houston SMM Food,125
288
+ 0.0,0.0,0.0,0.0,0.005281885550328628,0.0,0.0,103.5,8/9/2021,Houston SMM Food,126
289
+ 0.0,0.0,0.01913533089801548,0.0,0.0,0.21760885851354209,0.1684836471754212,140.942,9/11/2023,Houston SMM Food,127
290
+ 0.0,0.0,0.0,0.04769953315392536,0.0,0.0,0.0,140.87,9/12/2022,Houston SMM Food,128
291
+ 0.0,0.0,0.0,0.0,0.004650335585826283,0.0,0.0,105.88,9/13/2021,Houston SMM Food,129
292
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1620416253716551,129.531,9/18/2023,Houston SMM Food,130
293
+ 0.0,0.0,0.0,0.049721876494397986,0.0,0.0,0.0,145.85,9/19/2022,Houston SMM Food,131
294
+ 0.0,0.0,0.0,0.0,0.003903114863868561,0.0,0.0,111.54,9/20/2021,Houston SMM Food,132
295
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15510406342913777,135.992,9/25/2023,Houston SMM Food,133
296
+ 0.0,0.0,0.0,0.05649970535943224,0.0,0.0,0.0,150.89,9/26/2022,Houston SMM Food,134
297
+ 0.0,0.0,0.0,0.0,0.003332802359195532,0.0,0.0,100.18,9/27/2021,Houston SMM Food,135
298
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15857284440039643,134.53,9/4/2023,Houston SMM Food,136
299
+ 0.0,0.0,0.0,0.04990490981700915,0.0,0.0,0.0,130.92,9/5/2022,Houston SMM Food,137
300
+ 0.0,0.0,0.0,0.0,0.0032511524127564434,0.0,0.0,108.11,9/6/2021,Houston SMM Food,138
301
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14172447968285432,48.376,8/7/2023,Indianapolis SMM Food,124
302
+ 0.0,0.0024260878158616334,0.0,0.0,0.012808526067531899,0.0,0.0,46.59,8/8/2022,Indianapolis SMM Food,125
303
+ 0.0,0.0,0.0,0.0,0.003151564220508767,0.0,0.0,38.95,8/9/2021,Indianapolis SMM Food,126
304
+ 0.0,0.0,0.016644041455881685,0.0,0.0,0.11700205142709444,0.11446977205153618,49.036,9/11/2023,Indianapolis SMM Food,127
305
+ 0.0,0.0,0.0,0.023691657521331348,0.0,0.0,0.0,35.97,9/12/2022,Indianapolis SMM Food,128
306
+ 0.0,0.0,0.0,0.0,0.0022490848882767175,0.0,0.0,37.35,9/13/2021,Indianapolis SMM Food,129
307
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11645193260654113,51.603,9/18/2023,Indianapolis SMM Food,130
308
+ 0.0,0.0,0.0,0.0246961257538268,0.0,0.0,0.0,38.52,9/19/2022,Indianapolis SMM Food,131
309
+ 0.0,0.0,0.0,0.0,0.0029072329413917966,0.0,0.0,31.83,9/20/2021,Indianapolis SMM Food,132
310
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10009910802775024,53.418,9/25/2023,Indianapolis SMM Food,133
311
+ 0.0,0.0,0.0,0.028062573805723218,0.0,0.0,0.0,39.19,9/26/2022,Indianapolis SMM Food,134
312
+ 0.0,0.0,0.0,0.0,0.002647437657267423,0.0,0.0,31.38,9/27/2021,Indianapolis SMM Food,135
313
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10505450941526263,55.713,9/4/2023,Indianapolis SMM Food,136
314
+ 0.0,0.0,0.0,0.024787035718660904,0.0,0.0,0.0,46.84,9/5/2022,Indianapolis SMM Food,137
315
+ 0.0,0.0,0.0,0.0,0.0030024912122374,0.0,0.0,37.3,9/6/2021,Indianapolis SMM Food,138
316
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07383548067393458,96.535,8/7/2023,Jacksonville SMM Food,124
317
+ 0.0,0.0008658822942801401,0.0,0.0,0.007301484604295482,0.0,0.0,62.66,8/8/2022,Jacksonville SMM Food,125
318
+ 0.0,0.0,0.0,0.0,0.0019435161493304308,0.0,0.0,34.35,8/9/2021,Jacksonville SMM Food,126
319
+ 0.0,0.0,0.0069561155917302895,0.0,0.0,0.08053507618258654,0.059960356788899896,27.967,9/11/2023,Jacksonville SMM Food,127
320
+ 0.0,0.0,0.0,0.02082072414146757,0.0,0.0,0.0,27.95,9/12/2022,Jacksonville SMM Food,128
321
+ 0.0,0.0,0.0,0.0,0.0015767099505548275,0.0,0.0,32.77,9/13/2021,Jacksonville SMM Food,129
322
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06491575817641229,29.339,9/18/2023,Jacksonville SMM Food,130
323
+ 0.0,0.0,0.0,0.02170347183093534,0.0,0.0,0.0,26.19,9/19/2022,Jacksonville SMM Food,131
324
+ 0.0,0.0,0.0,0.0,0.001496297124516331,0.0,0.0,28.8,9/20/2021,Jacksonville SMM Food,132
325
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.049554013875123884,28.801,9/25/2023,Jacksonville SMM Food,133
326
+ 0.0,0.0,0.0,0.024661976783877985,0.0,0.0,0.0,25.24,9/26/2022,Jacksonville SMM Food,134
327
+ 0.0,0.0,0.0,0.0,0.0016119678819717068,0.0,0.0,25.69,9/27/2021,Jacksonville SMM Food,135
328
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07433102081268583,51.144,9/4/2023,Jacksonville SMM Food,136
329
+ 0.0,0.0,0.0,0.02178336541288693,0.0,0.0,0.0,43.45,9/5/2022,Jacksonville SMM Food,137
330
+ 0.0,0.0,0.0,0.0,0.0012927908186189051,0.0,0.0,31.77,9/6/2021,Jacksonville SMM Food,138
331
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11248761149653122,29.172,8/7/2023,Kansas City SMM Food,124
332
+ 0.0,0.0018331404008659269,0.0,0.0,0.0055076600234367145,0.0,0.0,35.15,8/8/2022,Kansas City SMM Food,125
333
+ 0.0,0.0,0.0,0.0,0.0016793909438039844,0.0,0.0,32.17,8/9/2021,Kansas City SMM Food,126
334
+ 0.0,0.0,0.0,0.0,0.0,0.08131822285155027,0.11050545094152626,33.379,9/11/2023,Kansas City SMM Food,127
335
+ 0.0,0.0,0.0,0.020919710852413544,0.0,0.0,0.0,31.54,9/12/2022,Kansas City SMM Food,128
336
+ 0.0,0.0,0.0,0.0,0.00130639914302542,0.0,0.0,35.16,9/13/2021,Kansas City SMM Food,129
337
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10555004955401387,30.958,9/18/2023,Kansas City SMM Food,130
338
+ 0.0,0.0,0.0,0.021806655337224045,0.0,0.0,0.0,30.39,9/19/2022,Kansas City SMM Food,131
339
+ 0.0,0.0,0.0,0.0,0.0012995949808221627,0.0,0.0,33.17,9/20/2021,Kansas City SMM Food,132
340
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10009910802775024,32.027,9/25/2023,Kansas City SMM Food,133
341
+ 0.0,0.0,0.0,0.024779225733846975,0.0,0.0,0.0,30.72,9/26/2022,Kansas City SMM Food,134
342
+ 0.0,0.0,0.0,0.0,0.0017282571996273786,0.0,0.0,30.48,9/27/2021,Kansas City SMM Food,135
343
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0882061446977205,31.622,9/4/2023,Kansas City SMM Food,136
344
+ 0.0,0.0,0.0,0.021886928747765332,0.0,0.0,0.0,33.43,9/5/2022,Kansas City SMM Food,137
345
+ 0.0,0.0,0.0,0.0,0.0012779453738117983,0.0,0.0,34.17,9/6/2021,Kansas City SMM Food,138
346
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.059960356788899896,28.985,8/7/2023,Knoxville SMM Food,124
347
+ 0.0,0.0009172922503781605,0.0,0.0,0.004641057182821841,0.0,0.0,24.48,8/8/2022,Knoxville SMM Food,125
348
+ 0.0,0.0,0.0,0.0,0.00217362054384059,0.0,0.0,22.62,8/9/2021,Knoxville SMM Food,126
349
+ 0.0,0.0,0.007657423696883808,0.0,0.0,0.05601546016597905,0.06095143706640238,34.993,9/11/2023,Knoxville SMM Food,127
350
+ 0.0,0.0,0.0,0.012082336514998791,0.0,0.0,0.0,21.57,9/12/2022,Knoxville SMM Food,128
351
+ 0.0,0.0,0.0,0.0,0.0016899064672090188,0.0,0.0,22.64,9/13/2021,Knoxville SMM Food,129
352
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05153617443012884,23.653,9/18/2023,Knoxville SMM Food,130
353
+ 0.0,0.0,0.0,0.012594597987226747,0.0,0.0,0.0,25.34,9/19/2022,Knoxville SMM Food,131
354
+ 0.0,0.0,0.0,0.0,0.0013614510008517755,0.0,0.0,23.4,9/20/2021,Knoxville SMM Food,132
355
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.055996035678889985,23.93,9/25/2023,Knoxville SMM Food,133
356
+ 0.0,0.0,0.0,0.014311428395501457,0.0,0.0,0.0,26.36,9/26/2022,Knoxville SMM Food,134
357
+ 0.0,0.0,0.0,0.0,0.0009154690964382679,0.0,0.0,25.75,9/27/2021,Knoxville SMM Food,135
358
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05302279484638256,27.206,9/4/2023,Knoxville SMM Food,136
359
+ 0.0,0.0,0.0,0.01264096049426039,0.0,0.0,0.0,23.09,9/5/2022,Knoxville SMM Food,137
360
+ 0.0,0.0,0.0,0.0,0.0013441313152434838,0.0,0.0,25.4,9/6/2021,Knoxville SMM Food,138
361
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05946481665014866,31.532,8/7/2023,Las Vegas SMM Food,124
362
+ 0.0,0.002099721240632628,0.0,0.0,0.003961259522696397,0.0,0.0,24.92,8/8/2022,Las Vegas SMM Food,125
363
+ 0.0,0.0,0.0,0.0,0.0010515523405034157,0.0,0.0,17.85,8/9/2021,Las Vegas SMM Food,126
364
+ 0.0,0.0,0.009369763221981868,0.0,0.0,0.08034252733962806,0.035678889990089196,34.959,9/11/2023,Las Vegas SMM Food,127
365
+ 0.0,0.0,0.0,0.0185917027305958,0.0,0.0,0.0,28.18,9/12/2022,Las Vegas SMM Food,128
366
+ 0.0,0.0,0.0,0.0,0.0012927908186189051,0.0,0.0,24.83,9/13/2021,Las Vegas SMM Food,129
367
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.048562933597621406,33.115,9/18/2023,Las Vegas SMM Food,130
368
+ 0.0,0.0,0.0,0.019379945382538788,0.0,0.0,0.0,26.13,9/19/2022,Las Vegas SMM Food,131
369
+ 0.0,0.0,0.0,0.0,0.001155470454153165,0.0,0.0,24.17,9/20/2021,Las Vegas SMM Food,132
370
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05302279484638256,30.334,9/25/2023,Las Vegas SMM Food,133
371
+ 0.0,0.0,0.0,0.022021719233974155,0.0,0.0,0.0,25.26,9/26/2022,Las Vegas SMM Food,134
372
+ 0.0,0.0,0.0,0.0,0.0013317601112375612,0.0,0.0,24.46,9/27/2021,Las Vegas SMM Food,135
373
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04707631318136769,30.934,9/4/2023,Las Vegas SMM Food,136
374
+ 0.0,0.0,0.0,0.019451285727142276,0.0,0.0,0.0,26.34,9/5/2022,Las Vegas SMM Food,137
375
+ 0.0,0.0,0.0,0.0,0.0016472258133885859,0.0,0.0,23.98,9/6/2021,Las Vegas SMM Food,138
376
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0639246778989098,10.063,8/7/2023,Little Rock/Pine Bluff SMM Food,124
377
+ 0.0,0.0014186837323228979,0.0,0.0,0.006373025743650996,0.0,0.0,8.89,8/8/2022,Little Rock/Pine Bluff SMM Food,125
378
+ 0.0,0.0,0.0,0.0,0.001933619186125693,0.0,0.0,10.01,8/9/2021,Little Rock/Pine Bluff SMM Food,126
379
+ 0.0,0.0,0.0067615890956558185,0.0,0.0,0.04907078091276023,0.055004955401387515,10.863,9/11/2023,Little Rock/Pine Bluff SMM Food,127
380
+ 0.0,0.0,0.0,0.015617921237149364,0.0,0.0,0.0,9.69,9/12/2022,Little Rock/Pine Bluff SMM Food,128
381
+ 0.0,0.0,0.0,0.0,0.0014356782248873107,0.0,0.0,11.67,9/13/2021,Little Rock/Pine Bluff SMM Food,129
382
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.062438057482656094,9.718,9/18/2023,Little Rock/Pine Bluff SMM Food,130
383
+ 0.0,0.0,0.0,0.01628008283607892,0.0,0.0,0.0,10.38,9/19/2022,Little Rock/Pine Bluff SMM Food,131
384
+ 0.0,0.0,0.0,0.0,0.0015482561813412057,0.0,0.0,9.39,9/20/2021,Little Rock/Pine Bluff SMM Food,132
385
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05252725470763132,9.803,9/25/2023,Little Rock/Pine Bluff SMM Food,133
386
+ 0.0,0.0,0.0,0.018499299465241616,0.0,0.0,0.0,9.19,9/26/2022,Little Rock/Pine Bluff SMM Food,134
387
+ 0.0,0.0,0.0,0.0,0.0015946481963634153,0.0,0.0,9.27,9/27/2021,Little Rock/Pine Bluff SMM Food,135
388
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04013875123885034,11.034,9/4/2023,Little Rock/Pine Bluff SMM Food,136
389
+ 0.0,0.0,0.0,0.016340012143976613,0.0,0.0,0.0,9.59,9/5/2022,Little Rock/Pine Bluff SMM Food,137
390
+ 0.0,0.0,0.0,0.0,0.0017777420156510687,0.0,0.0,11.85,9/6/2021,Little Rock/Pine Bluff SMM Food,138
391
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3062438057482656,114.624,8/7/2023,Los Angeles SMM Food,124
392
+ 0.0,0.019228478860571916,0.0,0.0,0.03378946950137623,0.0,0.0,106.07,8/8/2022,Los Angeles SMM Food,125
393
+ 0.0,0.0,0.0,0.0,0.010010778281592518,0.0,0.0,93.99,8/9/2021,Los Angeles SMM Food,126
394
+ 0.0,0.0,0.13303797876107476,0.0,0.0,0.3747884838535892,0.2522299306243806,131.228,9/11/2023,Los Angeles SMM Food,127
395
+ 0.0,0.0,0.0,0.10969678061239888,0.0,0.0,0.0,115.82,9/12/2022,Los Angeles SMM Food,128
396
+ 0.0,0.0,0.0,0.0,0.009888921922134182,0.0,0.0,119.97,9/13/2021,Los Angeles SMM Food,129
397
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.24727452923686818,119.603,9/18/2023,Los Angeles SMM Food,130
398
+ 0.0,0.0,0.0,0.11434765534026742,0.0,0.0,0.0,109.13,9/19/2022,Los Angeles SMM Food,131
399
+ 0.0,0.0,0.0,0.0,0.00820272681612694,0.0,0.0,99.09,9/20/2021,Los Angeles SMM Food,132
400
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.25966303270564917,114.482,9/25/2023,Los Angeles SMM Food,133
401
+ 0.0,0.0,0.0,0.12993493592533384,0.0,0.0,0.0,115.06,9/26/2022,Los Angeles SMM Food,134
402
+ 0.0,0.0,0.0,0.0,0.00794355009220286,0.0,0.0,98.9,9/27/2021,Los Angeles SMM Food,135
403
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2477700693756194,135.601,9/4/2023,Los Angeles SMM Food,136
404
+ 0.0,0.0,0.0,0.11476858539692965,0.0,0.0,0.0,107.08,9/5/2022,Los Angeles SMM Food,137
405
+ 0.0,0.0,0.0,0.0,0.008441491053441243,0.0,0.0,109.3,9/6/2021,Los Angeles SMM Food,138
406
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.049554013875123884,5.978,8/7/2023,Madison WI SMM Food,124
407
+ 0.0,0.000593236234973785,0.0,0.0,0.0031558941419108397,0.0,0.0,5.08,8/8/2022,Madison WI SMM Food,125
408
+ 0.0,0.0,0.0,0.0,0.0008400047520021403,0.0,0.0,5.58,8/9/2021,Madison WI SMM Food,126
409
+ 0.0,0.0,0.004571583640934544,0.0,0.0,0.034073713711936085,0.037165510406342916,7.98,9/11/2023,Madison WI SMM Food,127
410
+ 0.0,0.0,0.0,0.00930365997973997,0.0,0.0,0.0,6.03,9/12/2022,Madison WI SMM Food,128
411
+ 0.0,0.0,0.0,0.0,0.0004911367990351248,0.0,0.0,8.3,9/13/2021,Madison WI SMM Food,129
412
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.044598612487611496,7.618,9/18/2023,Madison WI SMM Food,130
413
+ 0.0,0.0,0.0,0.009698112368307879,0.0,0.0,0.0,6.79,9/19/2022,Madison WI SMM Food,131
414
+ 0.0,0.0,0.0,0.0,0.0004218580566019586,0.0,0.0,5.87,9/20/2021,Madison WI SMM Food,132
415
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.03815659068384539,7.501,9/25/2023,Madison WI SMM Food,133
416
+ 0.0,0.0,0.0,0.011020108853925868,0.0,0.0,0.0,6.51,9/26/2022,Madison WI SMM Food,134
417
+ 0.0,0.0,0.0,0.0,0.0006612408541165596,0.0,0.0,5.48,9/27/2021,Madison WI SMM Food,135
418
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04509415262636274,8.164,9/4/2023,Madison WI SMM Food,136
419
+ 0.0,0.0,0.0,0.009733812499659315,0.0,0.0,0.0,5.28,9/5/2022,Madison WI SMM Food,137
420
+ 0.0,0.0,0.0,0.0,0.00041381677399810894,0.0,0.0,5.27,9/6/2021,Madison WI SMM Food,138
421
+ 0.0,0.005007849599907721,0.0,0.0,0.011139032086932654,0.0,0.0,265.02,8/8/2022,Miami/West Palm Beach SMM Food,125
422
+ 0.0,0.0,0.0,0.0,0.0028466140417627763,0.0,0.0,109.22,8/9/2021,Miami/West Palm Beach SMM Food,126
423
+ 0.0,0.0,0.018040328170654842,0.0,0.0,0.135383570276492,0.0867195242814668,117.213,9/11/2023,Miami/West Palm Beach SMM Food,127
424
+ 0.0,0.0,0.0,0.040042460444501625,0.0,0.0,0.0,103.86,9/12/2022,Miami/West Palm Beach SMM Food,128
425
+ 0.0,0.0,0.0,0.0,0.0025509422660212277,0.0,0.0,106.45,9/13/2021,Miami/West Palm Beach SMM Food,129
426
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08225966303270565,115.904,9/18/2023,Miami/West Palm Beach SMM Food,130
427
+ 0.0,0.0,0.0,0.04174016266482536,0.0,0.0,0.0,95.09,9/19/2022,Miami/West Palm Beach SMM Food,131
428
+ 0.0,0.0,0.0,0.0,0.002568261951629519,0.0,0.0,104.62,9/20/2021,Miami/West Palm Beach SMM Food,132
429
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07036669970267592,103.499,9/25/2023,Miami/West Palm Beach SMM Food,133
430
+ 0.0,0.0,0.0,0.04742996560650661,0.0,0.0,0.0,111.66,9/26/2022,Miami/West Palm Beach SMM Food,134
431
+ 0.0,0.0,0.0,0.0,0.0022886727410956695,0.0,0.0,102.39,9/27/2021,Miami/West Palm Beach SMM Food,135
432
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10158572844400396,146.302,9/4/2023,Miami/West Palm Beach SMM Food,136
433
+ 0.0,0.0,0.0,0.04189381415960767,0.0,0.0,0.0,147.87,9/5/2022,Miami/West Palm Beach SMM Food,137
434
+ 0.0,0.0,0.0,0.0,0.0027909436237361245,0.0,0.0,104.06,9/6/2021,Miami/West Palm Beach SMM Food,138
435
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0931615460852329,24.866,8/7/2023,Milwaukee SMM Food,124
436
+ 0.0,0.001717034769678263,0.0,0.0,0.009219639785413772,0.0,0.0,23.28,8/8/2022,Milwaukee SMM Food,125
437
+ 0.0,0.0,0.0,0.0,0.0018352681142786086,0.0,0.0,19.3,8/9/2021,Milwaukee SMM Food,126
438
+ 0.0,0.0,0.01275815316445043,0.0,0.0,0.08156726192538118,0.062438057482656094,25.297,9/11/2023,Milwaukee SMM Food,127
439
+ 0.0,0.0,0.0,0.021252502340492276,0.0,0.0,0.0,18.62,9/12/2022,Milwaukee SMM Food,128
440
+ 0.0,0.0,0.0,0.0,0.0014635134339006364,0.0,0.0,20.78,9/13/2021,Milwaukee SMM Food,129
441
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06689791873141725,28.503,9/18/2023,Milwaukee SMM Food,130
442
+ 0.0,0.0,0.0,0.02215355637305754,0.0,0.0,0.0,20.56,9/19/2022,Milwaukee SMM Food,131
443
+ 0.0,0.0,0.0,0.0,0.001509905448922846,0.0,0.0,18.05,9/20/2021,Milwaukee SMM Food,132
444
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08275520317145689,24.272,9/25/2023,Milwaukee SMM Food,133
445
+ 0.0,0.0,0.0,0.02517341451994022,0.0,0.0,0.0,19.51,9/26/2022,Milwaukee SMM Food,134
446
+ 0.0,0.0,0.0,0.0,0.0013719665242568095,0.0,0.0,20.33,9/27/2021,Milwaukee SMM Food,135
447
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07284440039643211,28.938,9/4/2023,Milwaukee SMM Food,136
448
+ 0.0,0.0,0.0,0.02223510677772291,0.0,0.0,0.0,25.25,9/5/2022,Milwaukee SMM Food,137
449
+ 0.0,0.0,0.0,0.0,0.001925577903521843,0.0,0.0,24.08,9/6/2021,Milwaukee SMM Food,138
450
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1709613478691774,37.06,8/7/2023,Minneapolis/St. Paul SMM Food,124
451
+ 0.0,0.0038046255712315823,0.0,0.0,0.00971510650585097,0.0,0.0,46.84,8/8/2022,Minneapolis/St. Paul SMM Food,125
452
+ 0.0,0.0,0.0,0.0,0.002077125152594394,0.0,0.0,41.5,8/9/2021,Minneapolis/St. Paul SMM Food,126
453
+ 0.0,0.0,0.03094870136244261,0.0,0.0,0.1252957809638225,0.17393458870168482,38.324,9/11/2023,Minneapolis/St. Paul SMM Food,127
454
+ 0.0,0.0,0.0,0.038681592342424166,0.0,0.0,0.0,51.68,9/12/2022,Minneapolis/St. Paul SMM Food,128
455
+ 0.0,0.0,0.0,0.0,0.001091758753522664,0.0,0.0,45.98,9/13/2021,Minneapolis/St. Paul SMM Food,129
456
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1570862239841427,40.978,9/18/2023,Minneapolis/St. Paul SMM Food,130
457
+ 0.0,0.0,0.0,0.0403215970895781,0.0,0.0,0.0,40.48,9/19/2022,Minneapolis/St. Paul SMM Food,131
458
+ 0.0,0.0,0.0,0.0,0.002432178707564371,0.0,0.0,49.56,9/20/2021,Minneapolis/St. Paul SMM Food,132
459
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15262636273538155,38.141,9/25/2023,Minneapolis/St. Paul SMM Food,133
460
+ 0.0,0.0,0.0,0.04581802852379454,0.0,0.0,0.0,38.38,9/26/2022,Minneapolis/St. Paul SMM Food,134
461
+ 0.0,0.0,0.0,0.0,0.0014257812616825726,0.0,0.0,47.81,9/27/2021,Minneapolis/St. Paul SMM Food,135
462
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1645193260654113,40.776,9/4/2023,Minneapolis/St. Paul SMM Food,136
463
+ 0.0,0.0,0.0,0.04047002664468756,0.0,0.0,0.0,44.99,9/5/2022,Minneapolis/St. Paul SMM Food,137
464
+ 0.0,0.0,0.0,0.0,0.0022967140236995194,0.0,0.0,43.4,9/6/2021,Minneapolis/St. Paul SMM Food,138
465
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06194251734390485,48.944,8/7/2023,Mobile/Pensacola SMM Food,124
466
+ 0.0,0.0007766369210538014,0.0,0.0,0.006063745643502932,0.0,0.0,31.02,8/8/2022,Mobile/Pensacola SMM Food,125
467
+ 0.0,0.0,0.0,0.0,0.0015507304221423902,0.0,0.0,18.44,8/9/2021,Mobile/Pensacola SMM Food,126
468
+ 0.0,0.0,0.007016034816117654,0.0,0.0,0.06153590867568924,0.05153617443012884,18.764,9/11/2023,Mobile/Pensacola SMM Food,127
469
+ 0.0,0.0,0.0,0.016447031490323782,0.0,0.0,0.0,17.84,9/12/2022,Mobile/Pensacola SMM Food,128
470
+ 0.0,0.0,0.0,0.0,0.001671349661200135,0.0,0.0,18.48,9/13/2021,Mobile/Pensacola SMM Food,129
471
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05054509415262636,17.263,9/18/2023,Mobile/Pensacola SMM Food,130
472
+ 0.0,0.0,0.0,0.01714434533067197,0.0,0.0,0.0,15.41,9/19/2022,Mobile/Pensacola SMM Food,131
473
+ 0.0,0.0,0.0,0.0,0.0012228935159854428,0.0,0.0,17.3,9/20/2021,Mobile/Pensacola SMM Food,132
474
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.030723488602576808,16.84,9/25/2023,Mobile/Pensacola SMM Food,133
475
+ 0.0,0.0,0.0,0.019481373757693706,0.0,0.0,0.0,14.96,9/26/2022,Mobile/Pensacola SMM Food,134
476
+ 0.0,0.0,0.0,0.0,0.0012754711330106138,0.0,0.0,15.57,9/27/2021,Mobile/Pensacola SMM Food,135
477
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.053518334985133795,21.946,9/4/2023,Mobile/Pensacola SMM Food,136
478
+ 0.0,0.0,0.0,0.017207456111133626,0.0,0.0,0.0,23.31,9/5/2022,Mobile/Pensacola SMM Food,137
479
+ 0.0,0.0,0.0,0.0,0.0013367085928399302,0.0,0.0,17.9,9/6/2021,Mobile/Pensacola SMM Food,138
480
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08572844400396432,77.43,8/7/2023,Nashville SMM Food,124
481
+ 0.0,0.0024515039739325646,0.0,0.0,0.011818829747058097,0.0,0.0,56.6,8/8/2022,Nashville SMM Food,125
482
+ 0.0,0.0,0.0,0.0,0.002948676474811637,0.0,0.0,41.75,8/9/2021,Nashville SMM Food,126
483
+ 0.0,0.0,0.018863584556427716,0.0,0.0,0.1291559227775106,0.09613478691774033,54.687,9/11/2023,Nashville SMM Food,127
484
+ 0.0,0.0,0.0,0.023131705316610268,0.0,0.0,0.0,43.39,9/12/2022,Nashville SMM Food,128
485
+ 0.0,0.0,0.0,0.0,0.0023907351741445306,0.0,0.0,39.43,9/13/2021,Nashville SMM Food,129
486
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10951437066402378,55.368,9/18/2023,Nashville SMM Food,130
487
+ 0.0,0.0,0.0,0.02411243295492175,0.0,0.0,0.0,41.52,9/19/2022,Nashville SMM Food,131
488
+ 0.0,0.0,0.0,0.0,0.0027346546455091774,0.0,0.0,42.92,9/20/2021,Nashville SMM Food,132
489
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09217046580773042,58.347,9/25/2023,Nashville SMM Food,133
490
+ 0.0,0.0,0.0,0.0273993150200572,0.0,0.0,0.0,48.74,9/26/2022,Nashville SMM Food,134
491
+ 0.0,0.0,0.0,0.0,0.0031305331736986982,0.0,0.0,43.99,9/27/2021,Nashville SMM Food,135
492
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08225966303270565,54.91,9/4/2023,Nashville SMM Food,136
493
+ 0.0,0.0,0.0,0.024201194256313775,0.0,0.0,0.0,43.7,9/5/2022,Nashville SMM Food,137
494
+ 0.0,0.0,0.0,0.0,0.002930119668802753,0.0,0.0,44.1,9/6/2021,Nashville SMM Food,138
495
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05004955401387512,10.449,8/7/2023,New Orleans SMM Food,124
496
+ 0.0,0.0011893606697283578,0.0,0.0,0.006126220223732841,0.0,0.0,13.23,8/8/2022,New Orleans SMM Food,125
497
+ 0.0,0.0,0.0,0.0,0.0021148573248124577,0.0,0.0,14.12,8/9/2021,New Orleans SMM Food,126
498
+ 0.0,0.0,0.007795828665891241,0.0,0.0,0.0697753770970809,0.040634291377601585,12.088,9/11/2023,New Orleans SMM Food,127
499
+ 0.0,0.0,0.0,0.01804932909865379,0.0,0.0,0.0,9.64,9/12/2022,New Orleans SMM Food,128
500
+ 0.0,0.0,0.0,0.0,0.0012334090393904772,0.0,0.0,24.18,9/13/2021,New Orleans SMM Food,129
501
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05698711595639247,10.331,9/18/2023,New Orleans SMM Food,130
502
+ 0.0,0.0,0.0,0.01881457643298289,0.0,0.0,0.0,9.9,9/19/2022,New Orleans SMM Food,131
503
+ 0.0,0.0,0.0,0.0,0.001212996552780705,0.0,0.0,34.03,9/20/2021,New Orleans SMM Food,132
504
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04162537165510406,11.492,9/25/2023,New Orleans SMM Food,133
505
+ 0.0,0.0,0.0,0.02137928211724966,0.0,0.0,0.0,8.96,9/26/2022,New Orleans SMM Food,134
506
+ 0.0,0.0,0.0,0.0,0.0007688703289680858,0.0,0.0,17.31,9/27/2021,New Orleans SMM Food,135
507
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04162537165510406,18.667,9/4/2023,New Orleans SMM Food,136
508
+ 0.0,0.0,0.0,0.018883835570947957,0.0,0.0,0.0,19.88,9/5/2022,New Orleans SMM Food,137
509
+ 0.0,0.0,0.0,0.0,0.001574235709753643,0.0,0.0,7.57,9/6/2021,New Orleans SMM Food,138
510
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4534192269573835,246.856,8/7/2023,New York SMM Food,124
511
+ 0.0,0.039101892732193715,0.0,0.0,0.0494452281708712,0.0,0.0,205.05,8/8/2022,New York SMM Food,125
512
+ 0.0,0.0,0.0,0.0,0.015521531106030714,0.0,0.0,234.8,8/9/2021,New York SMM Food,126
513
+ 0.0,0.0,0.24068159947386805,0.0,0.0,0.520680218910273,0.410802775024777,288.514,9/11/2023,New York SMM Food,127
514
+ 0.0,0.0,0.0,0.17120571402939075,0.0,0.0,0.0,254.52,9/12/2022,New York SMM Food,128
515
+ 0.0,0.0,0.0,0.0,0.013122136089082036,0.0,0.0,230.57,9/13/2021,New York SMM Food,129
516
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.41873141724479684,509.862,9/18/2023,New York SMM Food,130
517
+ 0.0,0.0,0.0,0.1784644168917692,0.0,0.0,0.0,247.62,9/19/2022,New York SMM Food,131
518
+ 0.0,0.0,0.0,0.0,0.012023573173356115,0.0,0.0,230.26,9/20/2021,New York SMM Food,132
519
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.42913776015857286,303.344,9/25/2023,New York SMM Food,133
520
+ 0.0,0.0,0.0,0.20279176256454842,0.0,0.0,0.0,260.65,9/26/2022,New York SMM Food,134
521
+ 0.0,0.0,0.0,0.0,0.011220682033371742,0.0,0.0,237.2,9/27/2021,New York SMM Food,135
522
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4474727452923687,274.76,9/4/2023,New York SMM Food,136
523
+ 0.0,0.0,0.0,0.17912136984330115,0.0,0.0,0.0,223.46,9/5/2022,New York SMM Food,137
524
+ 0.0,0.0,0.0,0.0,0.01324461100874067,0.0,0.0,236.95,9/6/2021,New York SMM Food,138
525
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07482656095143707,53.749,8/7/2023,Norfolk/Portsmouth/Newport News SMM Food,124
526
+ 0.0,0.0011087798958443822,0.0,0.0,0.008415511525028807,0.0,0.0,62.84,8/8/2022,Norfolk/Portsmouth/Newport News SMM Food,125
527
+ 0.0,0.0,0.0,0.0,0.00208578499539854,0.0,0.0,53.72,8/9/2021,Norfolk/Portsmouth/Newport News SMM Food,126
528
+ 0.0,0.0,0.010047019244106654,0.0,0.0,0.08559141854246288,0.062438057482656094,66.739,9/11/2023,Norfolk/Portsmouth/Newport News SMM Food,127
529
+ 0.0,0.0,0.0,0.015531940702298817,0.0,0.0,0.0,56.23,9/12/2022,Norfolk/Portsmouth/Newport News SMM Food,128
530
+ 0.0,0.0,0.0,0.0,0.0010960886749247368,0.0,0.0,57.58,9/13/2021,Norfolk/Portsmouth/Newport News SMM Food,129
531
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06045589692765114,57.374,9/18/2023,Norfolk/Portsmouth/Newport News SMM Food,130
532
+ 0.0,0.0,0.0,0.016190456939540337,0.0,0.0,0.0,55.17,9/19/2022,Norfolk/Portsmouth/Newport News SMM Food,131
533
+ 0.0,0.0,0.0,0.0,0.0014499051094941215,0.0,0.0,47.98,9/20/2021,Norfolk/Portsmouth/Newport News SMM Food,132
534
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06442021803766104,71.472,9/25/2023,Norfolk/Portsmouth/Newport News SMM Food,133
535
+ 0.0,0.0,0.0,0.01839745623572133,0.0,0.0,0.0,47.55,9/26/2022,Norfolk/Portsmouth/Newport News SMM Food,134
536
+ 0.0,0.0,0.0,0.0,0.0011863984641679714,0.0,0.0,51.74,9/27/2021,Norfolk/Portsmouth/Newport News SMM Food,135
537
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05797819623389494,49.663,9/4/2023,Norfolk/Portsmouth/Newport News SMM Food,136
538
+ 0.0,0.0,0.0,0.01625005632294706,0.0,0.0,0.0,49.62,9/5/2022,Norfolk/Portsmouth/Newport News SMM Food,137
539
+ 0.0,0.0,0.0,0.0,0.0014202142198799074,0.0,0.0,80.86,9/6/2021,Norfolk/Portsmouth/Newport News SMM Food,138
540
+ 0.0,0.0012719631834588849,0.0,0.0,0.004641057182821841,0.0,0.0,2.43,8/8/2022,Oklahoma City SMM Food,125
541
+ 0.0,0.0,0.0,0.0,0.001920629421919474,0.0,0.0,2.79,8/9/2021,Oklahoma City SMM Food,126
542
+ 0.0,0.0,0.008075170402119658,0.0,0.0,0.05973936106606689,0.0639246778989098,5.321,9/11/2023,Oklahoma City SMM Food,127
543
+ 0.0,0.0,0.0,0.017613566913413724,0.0,0.0,0.0,4.4,9/12/2022,Oklahoma City SMM Food,128
544
+ 0.0,0.0,0.0,0.0,0.0016657826193974697,0.0,0.0,5.31,9/13/2021,Oklahoma City SMM Food,129
545
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06739345887016848,4.506,9/18/2023,Oklahoma City SMM Food,130
546
+ 0.0,0.0,0.0,0.01836033899387075,0.0,0.0,0.0,3.98,9/19/2022,Oklahoma City SMM Food,131
547
+ 0.0,0.0,0.0,0.0,0.0015340292967343948,0.0,0.0,3.66,9/20/2021,Oklahoma City SMM Food,132
548
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06095143706640238,6.145,9/25/2023,Oklahoma City SMM Food,133
549
+ 0.0,0.0,0.0,0.02086312538457761,0.0,0.0,0.0,3.72,9/26/2022,Oklahoma City SMM Food,134
550
+ 0.0,0.0,0.0,0.0,0.0010830989107185184,0.0,0.0,4.46,9/27/2021,Oklahoma City SMM Food,135
551
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06541129831516353,8.982,9/4/2023,Oklahoma City SMM Food,136
552
+ 0.0,0.0,0.0,0.018427926025991807,0.0,0.0,0.0,2.67,9/5/2022,Oklahoma City SMM Food,137
553
+ 0.0,0.0,0.0,0.0,0.002021454734567743,0.0,0.0,2.99,9/6/2021,Oklahoma City SMM Food,138
554
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04311199207135778,12.325,8/7/2023,Omaha SMM Food,124
555
+ 0.0,0.0009476183480764309,0.0,0.0,0.003898166382266192,0.0,0.0,15.49,8/8/2022,Omaha SMM Food,125
556
+ 0.0,0.0,0.0,0.0,0.000536291693656742,0.0,0.0,12.09,8/9/2021,Omaha SMM Food,126
557
+ 0.0,0.0,0.00745909950348901,0.0,0.0,0.04438741589312105,0.049554013875123884,13.324,9/11/2023,Omaha SMM Food,127
558
+ 0.0,0.0,0.0,0.009233480542505387,0.0,0.0,0.0,11.97,9/12/2022,Omaha SMM Food,128
559
+ 0.0,0.0,0.0,0.0,0.0005041265632413435,0.0,0.0,13.54,9/13/2021,Omaha SMM Food,129
560
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06045589692765114,12.73,9/18/2023,Omaha SMM Food,130
561
+ 0.0,0.0,0.0,0.0096249574987297,0.0,0.0,0.0,11.64,9/19/2022,Omaha SMM Food,131
562
+ 0.0,0.0,0.0,0.0,0.0006804162203257396,0.0,0.0,14.6,9/20/2021,Omaha SMM Food,132
563
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04558969276511397,13.377,9/25/2023,Omaha SMM Food,133
564
+ 0.0,0.0,0.0,0.010936981891184227,0.0,0.0,0.0,11.62,9/26/2022,Omaha SMM Food,134
565
+ 0.0,0.0,0.0,0.0,0.0004911367990351248,0.0,0.0,12.9,9/27/2021,Omaha SMM Food,135
566
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05004955401387512,14.921,9/4/2023,Omaha SMM Food,136
567
+ 0.0,0.0,0.0,0.00966038834039735,0.0,0.0,0.0,12.01,9/5/2022,Omaha SMM Food,137
568
+ 0.0,0.0,0.0,0.0,0.000555467059865922,0.0,0.0,13.82,9/6/2021,Omaha SMM Food,138
569
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15807730426164518,296.409,8/7/2023,Orlando/Daytona Beach/Melborne SMM Food,124
570
+ 0.0,0.0035978304669271864,0.0,0.0,0.014912249308739028,0.0,0.0,177.13,8/8/2022,Orlando/Daytona Beach/Melborne SMM Food,125
571
+ 0.0,0.0,0.0,0.0,0.005805187479779151,0.0,0.0,65.31,8/9/2021,Orlando/Daytona Beach/Melborne SMM Food,126
572
+ 0.0,0.0,0.024174453275719036,0.0,0.0,0.18581466537428856,0.1238850346878097,77.936,9/11/2023,Orlando/Daytona Beach/Melborne SMM Food,127
573
+ 0.0,0.0,0.0,0.04488872730475567,0.0,0.0,0.0,68.78,9/12/2022,Orlando/Daytona Beach/Melborne SMM Food,128
574
+ 0.0,0.0,0.0,0.0,0.003562906753705691,0.0,0.0,66.88,9/13/2021,Orlando/Daytona Beach/Melborne SMM Food,129
575
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13627353815659068,75.008,9/18/2023,Orlando/Daytona Beach/Melborne SMM Food,130
576
+ 0.0,0.0,0.0,0.046791899365486236,0.0,0.0,0.0,58.18,9/19/2022,Orlando/Daytona Beach/Melborne SMM Food,131
577
+ 0.0,0.0,0.0,0.0,0.003940847036086625,0.0,0.0,59.08,9/20/2021,Orlando/Daytona Beach/Melborne SMM Food,132
578
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11149653121902874,68.939,9/25/2023,Orlando/Daytona Beach/Melborne SMM Food,133
579
+ 0.0,0.0,0.0,0.053170328912353564,0.0,0.0,0.0,66.79,9/26/2022,Orlando/Daytona Beach/Melborne SMM Food,134
580
+ 0.0,0.0,0.0,0.0,0.004718377207858856,0.0,0.0,57.95,9/27/2021,Orlando/Daytona Beach/Melborne SMM Food,135
581
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17244796828543113,108.309,9/4/2023,Orlando/Daytona Beach/Melborne SMM Food,136
582
+ 0.0,0.0,0.0,0.0469641470254011,0.0,0.0,0.0,84.61,9/5/2022,Orlando/Daytona Beach/Melborne SMM Food,137
583
+ 0.0,0.0,0.0,0.0,0.004595902288200223,0.0,0.0,60.35,9/6/2021,Orlando/Daytona Beach/Melborne SMM Food,138
584
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.028245787908820614,6.148,8/7/2023,Paducah KY/Cape Girardeau MO SMM Food,124
585
+ 0.0,0.00036420199235732373,0.0,0.0,0.0035888862821181287,0.0,0.0,5.95,8/8/2022,Paducah KY/Cape Girardeau MO SMM Food,125
586
+ 0.0,0.0,0.0,0.0,0.0016602155775948047,0.0,0.0,6.97,8/9/2021,Paducah KY/Cape Girardeau MO SMM Food,126
587
+ 0.0,0.0,0.0033689794894980066,0.0,0.0,0.02940059048808853,0.036669970267591674,5.015,9/11/2023,Paducah KY/Cape Girardeau MO SMM Food,127
588
+ 0.0,0.0,0.0,0.008585794855104294,0.0,0.0,0.0,5.9,9/12/2022,Paducah KY/Cape Girardeau MO SMM Food,128
589
+ 0.0,0.0,0.0,0.0,0.0006470139695097488,0.0,0.0,5.93,9/13/2021,Paducah KY/Cape Girardeau MO SMM Food,129
590
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0421209117938553,5.725,9/18/2023,Paducah KY/Cape Girardeau MO SMM Food,130
591
+ 0.0,0.0,0.0,0.008949811523566999,0.0,0.0,0.0,4.53,9/19/2022,Paducah KY/Cape Girardeau MO SMM Food,131
592
+ 0.0,0.0,0.0,0.0,0.001383719168062436,0.0,0.0,5.28,9/20/2021,Paducah KY/Cape Girardeau MO SMM Food,132
593
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.03815659068384539,4.811,9/25/2023,Paducah KY/Cape Girardeau MO SMM Food,133
594
+ 0.0,0.0,0.0,0.010169803507137157,0.0,0.0,0.0,6.14,9/26/2022,Paducah KY/Cape Girardeau MO SMM Food,134
595
+ 0.0,0.0,0.0,0.0,0.0010738205077140764,0.0,0.0,5.48,9/27/2021,Paducah KY/Cape Girardeau MO SMM Food,135
596
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.024777006937561942,6.809,9/4/2023,Paducah KY/Cape Girardeau MO SMM Food,136
597
+ 0.0,0.0,0.0,0.008982757054847872,0.0,0.0,0.0,7.88,9/5/2022,Paducah KY/Cape Girardeau MO SMM Food,137
598
+ 0.0,0.0,0.0,0.0,0.0006903131835304776,0.0,0.0,7.07,9/6/2021,Paducah KY/Cape Girardeau MO SMM Food,138
599
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2522299306243806,136.614,8/7/2023,Philadelphia SMM Food,124
600
+ 0.0,0.006726039649498299,0.0,0.0,0.0256807638356943,0.0,0.0,135.86,8/8/2022,Philadelphia SMM Food,125
601
+ 0.0,0.0,0.0,0.0,0.007499423868390242,0.0,0.0,130.86,8/9/2021,Philadelphia SMM Food,126
602
+ 0.0,0.0,0.04194430100389289,0.0,0.0,0.2407575070389005,0.21754212091179384,175.883,9/11/2023,Philadelphia SMM Food,127
603
+ 0.0,0.0,0.0,0.06751901436081623,0.0,0.0,0.0,157.21,9/12/2022,Philadelphia SMM Food,128
604
+ 0.0,0.0,0.0,0.0,0.006012405146878353,0.0,0.0,149.83,9/13/2021,Philadelphia SMM Food,129
605
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20416253716551042,235.367,9/18/2023,Philadelphia SMM Food,130
606
+ 0.0,0.0,0.0,0.07038165514606878,0.0,0.0,0.0,153.26,9/19/2022,Philadelphia SMM Food,131
607
+ 0.0,0.0,0.0,0.0,0.0061806535213589,0.0,0.0,146.17,9/20/2021,Philadelphia SMM Food,132
608
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2358771060455897,157.971,9/25/2023,Philadelphia SMM Food,133
609
+ 0.0,0.0,0.0,0.07997571812552183,0.0,0.0,0.0,135.14,9/26/2022,Philadelphia SMM Food,134
610
+ 0.0,0.0,0.0,0.0,0.00549714450003168,0.0,0.0,145.33,9/27/2021,Philadelphia SMM Food,135
611
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2309217046580773,165.02,9/4/2023,Philadelphia SMM Food,136
612
+ 0.0,0.0,0.0,0.07064074003892257,0.0,0.0,0.0,151.89,9/5/2022,Philadelphia SMM Food,137
613
+ 0.0,0.0,0.0,0.0,0.0056214751002912015,0.0,0.0,155.51,9/6/2021,Philadelphia SMM Food,138
614
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17195242814667988,79.849,8/7/2023,Phoenix/Prescott SMM Food,124
615
+ 0.0,0.0,0.0,0.0,0.014418019708702422,0.0,0.0,66.86,8/8/2022,Phoenix/Prescott SMM Food,125
616
+ 0.0,0.0,0.0,0.0,0.005271370026923594,0.0,0.0,46.12,8/9/2021,Phoenix/Prescott SMM Food,126
617
+ 0.0,0.0,0.0,0.0,0.0,0.001808959402470655,0.13627353815659068,80.322,9/11/2023,Phoenix/Prescott SMM Food,127
618
+ 0.0,0.0,0.0,0.036806299803701564,0.0,0.0,0.0,73.57,9/12/2022,Phoenix/Prescott SMM Food,128
619
+ 0.0,0.0,0.0,0.0,0.0034243492688393585,0.0,0.0,56.9,9/13/2021,Phoenix/Prescott SMM Food,129
620
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1630327056491576,72.968,9/18/2023,Phoenix/Prescott SMM Food,130
621
+ 0.0,0.0,0.0,0.0383667967368777,0.0,0.0,0.0,67.09,9/19/2022,Phoenix/Prescott SMM Food,131
622
+ 0.0,0.0,0.0,0.0,0.002687025510086375,0.0,0.0,54.17,9/20/2021,Phoenix/Prescott SMM Food,132
623
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1367690782953419,71.044,9/25/2023,Phoenix/Prescott SMM Food,133
624
+ 0.0,0.0,0.0,0.04359675990047249,0.0,0.0,0.0,75.15,9/26/2022,Phoenix/Prescott SMM Food,134
625
+ 0.0,0.0,0.0,0.0,0.0027371288863103616,0.0,0.0,54.23,9/27/2021,Phoenix/Prescott SMM Food,135
626
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14866204162537167,80.716,9/4/2023,Phoenix/Prescott SMM Food,136
627
+ 0.0,0.0,0.0,0.038508030393034846,0.0,0.0,0.0,67.72,9/5/2022,Phoenix/Prescott SMM Food,137
628
+ 0.0,0.0,0.0,0.0,0.0037181653639800187,0.0,0.0,56.91,9/6/2021,Phoenix/Prescott SMM Food,138
629
+ 0.0,0.0022663703679840757,0.0,0.0,0.00748705266438432,0.0,0.0,50.92,8/8/2022,Pittsburgh SMM Food,125
630
+ 0.0,0.0,0.0,0.0,0.003074244195471751,0.0,0.0,59.65,8/9/2021,Pittsburgh SMM Food,126
631
+ 0.0,0.0,0.009616613547803052,0.0,0.0,0.0779249674907126,0.11050545094152626,57.215,9/11/2023,Pittsburgh SMM Food,127
632
+ 0.0,0.0,0.0,0.025851136933559334,0.0,0.0,0.0,57.81,9/12/2022,Pittsburgh SMM Food,128
633
+ 0.0,0.0,0.0,0.0,0.002534859700813528,0.0,0.0,64.84,9/13/2021,Pittsburgh SMM Food,129
634
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10604558969276512,50.418,9/18/2023,Pittsburgh SMM Food,130
635
+ 0.0,0.0,0.0,0.026947161800410718,0.0,0.0,0.0,49.22,9/19/2022,Pittsburgh SMM Food,131
636
+ 0.0,0.0,0.0,0.0,0.002456921115576216,0.0,0.0,55.17,9/20/2021,Pittsburgh SMM Food,132
637
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10059464816650149,54.89,9/25/2023,Pittsburgh SMM Food,133
638
+ 0.0,0.0,0.0,0.030620459431281187,0.0,0.0,0.0,46.36,9/26/2022,Pittsburgh SMM Food,134
639
+ 0.0,0.0,0.0,0.0,0.002446405592171182,0.0,0.0,58.95,9/27/2021,Pittsburgh SMM Food,135
640
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08870168483647176,59.663,9/4/2023,Pittsburgh SMM Food,136
641
+ 0.0,0.0,0.0,0.027046358148388426,0.0,0.0,0.0,56.47,9/5/2022,Pittsburgh SMM Food,137
642
+ 0.0,0.0,0.0,0.0,0.0023140337093078105,0.0,0.0,57.77,9/6/2021,Pittsburgh SMM Food,138
643
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10257680872150644,31.759,8/7/2023,Portland OR SMM Food,124
644
+ 0.0,0.002691513375716019,0.0,0.0,0.007488289784784913,0.0,0.0,32.69,8/8/2022,Portland OR SMM Food,125
645
+ 0.0,0.0,0.0,0.0,0.0017870204186555107,0.0,0.0,36.91,8/9/2021,Portland OR SMM Food,126
646
+ 0.0,0.0,0.020675086178223175,0.0,0.0,0.10859833173904791,0.09613478691774033,41.43,9/11/2023,Portland OR SMM Food,127
647
+ 0.0,0.0,0.0,0.025917320120911743,0.0,0.0,0.0,37.08,9/12/2022,Portland OR SMM Food,128
648
+ 0.0,0.0,0.0,0.0,0.0024290859065628904,0.0,0.0,40.37,9/13/2021,Portland OR SMM Food,129
649
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11050545094152626,36.716,9/18/2023,Portland OR SMM Food,130
650
+ 0.0,0.0,0.0,0.02701615099834603,0.0,0.0,0.0,34.13,9/19/2022,Portland OR SMM Food,131
651
+ 0.0,0.0,0.0,0.0,0.0006643336551180404,0.0,0.0,39.78,9/20/2021,Portland OR SMM Food,132
652
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.099603567888999,39.153,9/25/2023,Portland OR SMM Food,133
653
+ 0.0,0.0,0.0,0.030698852877443856,0.0,0.0,0.0,34.55,9/26/2022,Portland OR SMM Food,134
654
+ 0.0,0.0,0.0,0.0,0.0015080497683219573,0.0,0.0,36.01,9/27/2021,Portland OR SMM Food,135
655
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10356788899900891,45.084,9/4/2023,Portland OR SMM Food,136
656
+ 0.0,0.0,0.0,0.027115601306424007,0.0,0.0,0.0,32.45,9/5/2022,Portland OR SMM Food,137
657
+ 0.0,0.0,0.0,0.0,0.0023134151491075146,0.0,0.0,41.15,9/6/2021,Portland OR SMM Food,138
658
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05153617443012884,35.059,8/7/2023,Providence RI/New Bedford MA SMM Food,124
659
+ 0.0,0.0014989756862287948,0.0,0.0,0.006621068383969743,0.0,0.0,36.29,8/8/2022,Providence RI/New Bedford MA SMM Food,125
660
+ 0.0,0.0,0.0,0.0,0.0017084632732179026,0.0,0.0,35.9,8/9/2021,Providence RI/New Bedford MA SMM Food,126
661
+ 0.0,0.0,0.005980529346775456,0.0,0.0,0.05103785298168852,0.05004955401387512,39.575,9/11/2023,Providence RI/New Bedford MA SMM Food,127
662
+ 0.0,0.0,0.0,0.016572692519385028,0.0,0.0,0.0,47.61,9/12/2022,Providence RI/New Bedford MA SMM Food,128
663
+ 0.0,0.0,0.0,0.0,0.0012748525728103176,0.0,0.0,36.32,9/13/2021,Providence RI/New Bedford MA SMM Food,129
664
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05450941526263627,46.736,9/18/2023,Providence RI/New Bedford MA SMM Food,130
665
+ 0.0,0.0,0.0,0.01727533407353234,0.0,0.0,0.0,43.68,9/19/2022,Providence RI/New Bedford MA SMM Food,131
666
+ 0.0,0.0,0.0,0.0,0.0017511439270383351,0.0,0.0,32.15,9/20/2021,Providence RI/New Bedford MA SMM Food,132
667
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.053518334985133795,44.89,9/25/2023,Providence RI/New Bedford MA SMM Food,133
668
+ 0.0,0.0,0.0,0.01963021820698563,0.0,0.0,0.0,43.55,9/26/2022,Providence RI/New Bedford MA SMM Food,134
669
+ 0.0,0.0,0.0,0.0,0.0016719682214004312,0.0,0.0,32.14,9/27/2021,Providence RI/New Bedford MA SMM Food,135
670
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.052031714568880075,36.566,9/4/2023,Providence RI/New Bedford MA SMM Food,136
671
+ 0.0,0.0,0.0,0.017338927045711716,0.0,0.0,0.0,40.72,9/5/2022,Providence RI/New Bedford MA SMM Food,137
672
+ 0.0,0.0,0.0,0.0,0.0022255796006654645,0.0,0.0,34.4,9/6/2021,Providence RI/New Bedford MA SMM Food,138
673
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10208126858275521,74.844,8/7/2023,Raleigh/Durham/Fayetteville SMM Food,124
674
+ 0.0,0.002229401410789994,0.0,0.0,0.014169977068383676,0.0,0.0,95.13,8/8/2022,Raleigh/Durham/Fayetteville SMM Food,125
675
+ 0.0,0.0,0.0,0.0,0.0034323905514432084,0.0,0.0,67.86,8/9/2021,Raleigh/Durham/Fayetteville SMM Food,126
676
+ 0.0,0.0,0.017138164073892976,0.0,0.0,0.12866985361914052,0.09217046580773042,92.348,9/11/2023,Raleigh/Durham/Fayetteville SMM Food,127
677
+ 0.0,0.0,0.0,0.03276343729674159,0.0,0.0,0.0,84.3,9/12/2022,Raleigh/Durham/Fayetteville SMM Food,128
678
+ 0.0,0.0,0.0,0.0,0.0024866120051904306,0.0,0.0,74.59,9/13/2021,Raleigh/Durham/Fayetteville SMM Food,129
679
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09464816650148662,87.201,9/18/2023,Raleigh/Durham/Fayetteville SMM Food,130
680
+ 0.0,0.0,0.0,0.034152526763903276,0.0,0.0,0.0,76.26,9/19/2022,Raleigh/Durham/Fayetteville SMM Food,131
681
+ 0.0,0.0,0.0,0.0,0.0025843445168372186,0.0,0.0,62.15,9/20/2021,Raleigh/Durham/Fayetteville SMM Food,132
682
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09266600594648167,108.314,9/25/2023,Raleigh/Durham/Fayetteville SMM Food,133
683
+ 0.0,0.0,0.0,0.03880802245868132,0.0,0.0,0.0,60.35,9/26/2022,Raleigh/Durham/Fayetteville SMM Food,134
684
+ 0.0,0.0,0.0,0.0,0.00243712718916674,0.0,0.0,64.26,9/27/2021,Raleigh/Durham/Fayetteville SMM Food,135
685
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07730426164519326,60.95,9/4/2023,Raleigh/Durham/Fayetteville SMM Food,136
686
+ 0.0,0.0,0.0,0.03427824709389885,0.0,0.0,0.0,65.5,9/5/2022,Raleigh/Durham/Fayetteville SMM Food,137
687
+ 0.0,0.0,0.0,0.0,0.0019868153633511593,0.0,0.0,98.44,9/6/2021,Raleigh/Durham/Fayetteville SMM Food,138
688
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.6694747274529237,288.005,8/7/2023,Rem US East North Central SMM Food,124
689
+ 0.0,0.010814575259181308,0.0,0.0,0.07214515040133847,0.0,0.0,308.06,8/8/2022,Rem US East North Central SMM Food,125
690
+ 0.0,0.0,0.0,0.0,0.02009021674541791,0.0,0.0,247.25,8/9/2021,Rem US East North Central SMM Food,126
691
+ 0.0,0.0,0.07424624851147829,0.0,0.0,0.5637364309077629,0.6283448959365708,263.553,9/11/2023,Rem US East North Central SMM Food,127
692
+ 0.0,0.0,0.0,0.1610144344327281,0.0,0.0,0.0,240.58,9/12/2022,Rem US East North Central SMM Food,128
693
+ 0.0,0.0,0.0,0.0,0.016926281320903215,0.0,0.0,240.68,9/13/2021,Rem US East North Central SMM Food,129
694
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5926660059464817,298.802,9/18/2023,Rem US East North Central SMM Food,130
695
+ 0.0,0.0,0.0,0.16784105194697213,0.0,0.0,0.0,230.68,9/19/2022,Rem US East North Central SMM Food,131
696
+ 0.0,0.0,0.0,0.0,0.016729579177209047,0.0,0.0,202.81,9/20/2021,Rem US East North Central SMM Food,132
697
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5812685827552032,297.755,9/25/2023,Rem US East North Central SMM Food,133
698
+ 0.0,0.0,0.0,0.1907202755058764,0.0,0.0,0.0,247.8,9/26/2022,Rem US East North Central SMM Food,134
699
+ 0.0,0.0,0.0,0.0,0.014327709919459187,0.0,0.0,202.26,9/27/2021,Rem US East North Central SMM Food,135
700
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5827552031714569,348.214,9/4/2023,Rem US East North Central SMM Food,136
701
+ 0.0,0.0,0.0,0.16845889879914241,0.0,0.0,0.0,298.88,9/5/2022,Rem US East North Central SMM Food,137
702
+ 0.0,0.0,0.0,0.0,0.015420087233182148,0.0,0.0,258.8,9/6/2021,Rem US East North Central SMM Food,138
703
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.28344895936570863,84.899,8/7/2023,Rem US Middle Atlantic SMM Food,124
704
+ 0.0,0.004143700225496054,0.0,0.0,0.0231415742134787,0.0,0.0,71.81,8/8/2022,Rem US Middle Atlantic SMM Food,125
705
+ 0.0,0.0,0.0,0.0,0.006617357022767966,0.0,0.0,78.23,8/9/2021,Rem US Middle Atlantic SMM Food,126
706
+ 0.0,0.0,0.028037555383228337,0.0,0.0,0.20463726833171583,0.267591674925669,91.266,9/11/2023,Rem US Middle Atlantic SMM Food,127
707
+ 0.0,0.0,0.0,0.05392961586570856,0.0,0.0,0.0,79.8,9/12/2022,Rem US Middle Atlantic SMM Food,128
708
+ 0.0,0.0,0.0,0.0,0.005358587015165347,0.0,0.0,82.84,9/13/2021,Rem US Middle Atlantic SMM Food,129
709
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2968285431119921,95.654,9/18/2023,Rem US Middle Atlantic SMM Food,130
710
+ 0.0,0.0,0.0,0.056216099457233604,0.0,0.0,0.0,79.34,9/19/2022,Rem US Middle Atlantic SMM Food,131
711
+ 0.0,0.0,0.0,0.0,0.005923332478035712,0.0,0.0,79.18,9/20/2021,Rem US Middle Atlantic SMM Food,132
712
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.288404360753221,92.07,9/25/2023,Rem US Middle Atlantic SMM Food,133
713
+ 0.0,0.0,0.0,0.06387918718332888,0.0,0.0,0.0,76.85,9/26/2022,Rem US Middle Atlantic SMM Food,134
714
+ 0.0,0.0,0.0,0.0,0.004886007022139106,0.0,0.0,78.62,9/27/2021,Rem US Middle Atlantic SMM Food,135
715
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.25421209117938554,92.244,9/4/2023,Rem US Middle Atlantic SMM Food,136
716
+ 0.0,0.0,0.0,0.05642303894016692,0.0,0.0,0.0,90.03,9/5/2022,Rem US Middle Atlantic SMM Food,137
717
+ 0.0,0.0,0.0,0.0,0.005541680834453002,0.0,0.0,88.71,9/6/2021,Rem US Middle Atlantic SMM Food,138
718
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3865213082259663,129.148,8/7/2023,Rem US Mountain SMM Food,124
719
+ 0.0,0.00753329148822845,0.0,0.0,0.02747273273595218,0.0,0.0,113.3,8/8/2022,Rem US Mountain SMM Food,125
720
+ 0.0,0.0,0.0,0.0,0.007616950306446507,0.0,0.0,115.63,8/9/2021,Rem US Mountain SMM Food,126
721
+ 0.0,0.0,0.023499729051807798,0.0,0.0,0.3230963384624684,0.3295341922695738,135.595,9/11/2023,Rem US Mountain SMM Food,127
722
+ 0.0,0.0,0.0,0.08969502904489553,0.0,0.0,0.0,124.27,9/12/2022,Rem US Mountain SMM Food,128
723
+ 0.0,0.0,0.0,0.0,0.005267040105521521,0.0,0.0,115.0,9/13/2021,Rem US Mountain SMM Food,129
724
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3637264618434093,137.112,9/18/2023,Rem US Mountain SMM Food,130
725
+ 0.0,0.0,0.0,0.09349787851239232,0.0,0.0,0.0,126.58,9/19/2022,Rem US Mountain SMM Food,131
726
+ 0.0,0.0,0.0,0.0,0.004318168758267262,0.0,0.0,118.66,9/20/2021,Rem US Mountain SMM Food,132
727
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3399405351833498,137.733,9/25/2023,Rem US Mountain SMM Food,133
728
+ 0.0,0.0,0.0,0.10624302537960408,0.0,0.0,0.0,125.46,9/26/2022,Rem US Mountain SMM Food,134
729
+ 0.0,0.0,0.0,0.0,0.0057761151503652325,0.0,0.0,115.09,9/27/2021,Rem US Mountain SMM Food,135
730
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.31714568880079286,153.818,9/4/2023,Rem US Mountain SMM Food,136
731
+ 0.0,0.0,0.0,0.09384205752517928,0.0,0.0,0.0,123.49,9/5/2022,Rem US Mountain SMM Food,137
732
+ 0.0,0.0,0.0,0.0,0.005829929887790996,0.0,0.0,119.33,9/6/2021,Rem US Mountain SMM Food,138
733
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14816650148662042,95.632,8/7/2023,Rem US New England SMM Food,124
734
+ 0.0,0.0027053767346638,0.0,0.0,0.012870382087561513,0.0,0.0,92.11,8/8/2022,Rem US New England SMM Food,125
735
+ 0.0,0.0,0.0,0.0,0.0037107426415764655,0.0,0.0,93.54,8/9/2021,Rem US New England SMM Food,126
736
+ 0.0,0.0,0.016692145621939145,0.0,0.0,0.10162023020001978,0.14717542120911795,96.91,9/11/2023,Rem US New England SMM Food,127
737
+ 0.0,0.0,0.0,0.02729342543083433,0.0,0.0,0.0,108.12,9/12/2022,Rem US New England SMM Food,128
738
+ 0.0,0.0,0.0,0.0,0.003017336657044507,0.0,0.0,105.63,9/13/2021,Rem US New England SMM Food,129
739
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14568880079286423,104.654,9/18/2023,Rem US New England SMM Food,130
740
+ 0.0,0.0,0.0,0.028450599800614283,0.0,0.0,0.0,107.99,9/19/2022,Rem US New England SMM Food,131
741
+ 0.0,0.0,0.0,0.0,0.001866196124293415,0.0,0.0,103.16,9/20/2021,Rem US New England SMM Food,132
742
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1377601585728444,103.237,9/25/2023,Rem US New England SMM Food,133
743
+ 0.0,0.0,0.0,0.032328838321626044,0.0,0.0,0.0,110.46,9/26/2022,Rem US New England SMM Food,134
744
+ 0.0,0.0,0.0,0.0,0.002290528421696558,0.0,0.0,93.03,9/27/2021,Rem US New England SMM Food,135
745
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13181367690782952,95.746,9/4/2023,Rem US New England SMM Food,136
746
+ 0.0,0.0,0.0,0.028555330519776528,0.0,0.0,0.0,94.74,9/5/2022,Rem US New England SMM Food,137
747
+ 0.0,0.0,0.0,0.0,0.0022682602544858974,0.0,0.0,92.71,9/6/2021,Rem US New England SMM Food,138
748
+ 0.0,0.006359527097316345,0.0,0.0,0.02227744561366501,0.0,0.0,56.31,8/8/2022,Rem US Pacific SMM Food,125
749
+ 0.0,0.0,0.0,0.0,0.006462098412493638,0.0,0.0,52.58,8/9/2021,Rem US Pacific SMM Food,126
750
+ 0.0,0.0,0.04350177887159544,0.0,0.0,0.2505022822201761,0.26957383548067393,68.969,9/11/2023,Rem US Pacific SMM Food,127
751
+ 0.0,0.0,0.0,0.07303394106363369,0.0,0.0,0.0,64.99,9/12/2022,Rem US Pacific SMM Food,128
752
+ 0.0,0.0,0.0,0.0,0.005756939784156053,0.0,0.0,60.43,9/13/2021,Rem US Pacific SMM Food,129
753
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2755203171456888,59.672,9/18/2023,Rem US Pacific SMM Food,130
754
+ 0.0,0.0,0.0,0.07613040119907764,0.0,0.0,0.0,59.55,9/19/2022,Rem US Pacific SMM Food,131
755
+ 0.0,0.0,0.0,0.0,0.006201684568168969,0.0,0.0,50.8,9/20/2021,Rem US Pacific SMM Food,132
756
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.25173439048562934,59.2,9/25/2023,Rem US Pacific SMM Food,133
757
+ 0.0,0.0,0.0,0.08650810352908421,0.0,0.0,0.0,58.94,9/26/2022,Rem US Pacific SMM Food,134
758
+ 0.0,0.0,0.0,0.0,0.00586766206000906,0.0,0.0,56.23,9/27/2021,Rem US Pacific SMM Food,135
759
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2512388503468781,68.417,9/4/2023,Rem US Pacific SMM Food,136
760
+ 0.0,0.0,0.0,0.07641064808426322,0.0,0.0,0.0,64.25,9/5/2022,Rem US Pacific SMM Food,137
761
+ 0.0,0.0,0.0,0.0,0.006398386711863137,0.0,0.0,56.78,9/6/2021,Rem US Pacific SMM Food,138
762
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.6902874132804757,361.601,8/7/2023,Rem US South Atlantic SMM Food,124
763
+ 0.0,0.012989967334070573,0.0,0.0,0.07146720842181392,0.0,0.0,306.04,8/8/2022,Rem US South Atlantic SMM Food,125
764
+ 0.0,0.0,0.0,0.0,0.021449812065668792,0.0,0.0,216.74,8/9/2021,Rem US South Atlantic SMM Food,126
765
+ 0.0,0.0,0.07827180767102376,0.0,0.0,0.7032422127774433,0.5802775024777007,251.083,9/11/2023,Rem US South Atlantic SMM Food,127
766
+ 0.0,0.0,0.0,0.17196903338655478,0.0,0.0,0.0,233.99,9/12/2022,Rem US South Atlantic SMM Food,128
767
+ 0.0,0.0,0.0,0.0,0.015825244164376112,0.0,0.0,221.21,9/13/2021,Rem US South Atlantic SMM Food,129
768
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.6040634291377601,232.236,9/18/2023,Rem US South Atlantic SMM Food,130
769
+ 0.0,0.0,0.0,0.17926009905695495,0.0,0.0,0.0,215.08,9/19/2022,Rem US South Atlantic SMM Food,131
770
+ 0.0,0.0,0.0,0.0,0.017987112064411077,0.0,0.0,197.7,9/20/2021,Rem US South Atlantic SMM Food,132
771
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5708622398414271,309.873,9/25/2023,Rem US South Atlantic SMM Food,133
772
+ 0.0,0.0,0.0,0.20369590803657825,0.0,0.0,0.0,210.58,9/26/2022,Rem US South Atlantic SMM Food,134
773
+ 0.0,0.0,0.0,0.0,0.014305441752248528,0.0,0.0,213.12,9/27/2021,Rem US South Atlantic SMM Food,135
774
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5802775024777007,234.028,9/4/2023,Rem US South Atlantic SMM Food,136
775
+ 0.0,0.0,0.0,0.17991998108708984,0.0,0.0,0.0,215.63,9/5/2022,Rem US South Atlantic SMM Food,137
776
+ 0.0,0.0,0.0,0.0,0.01699123014193431,0.0,0.0,279.36,9/6/2021,Rem US South Atlantic SMM Food,138
777
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.9940535183349851,402.383,8/7/2023,Rem US South Central SMM Food,124
778
+ 0.0,0.014466126242031146,0.0,0.0,0.09628013229649275,0.0,0.0,349.19,8/8/2022,Rem US South Central SMM Food,125
779
+ 0.0,0.0,0.0,0.0,0.026810254761435028,0.0,0.0,321.57,8/9/2021,Rem US South Central SMM Food,126
780
+ 0.0,0.0,0.0887623135688707,0.0,0.0,0.8841922317358683,0.8275520317145688,406.505,9/11/2023,Rem US South Central SMM Food,127
781
+ 0.0,0.0,0.0,0.23375662511916412,0.0,0.0,0.0,389.86,9/12/2022,Rem US South Central SMM Food,128
782
+ 0.0,0.0,0.0,0.0,0.023796629465592297,0.0,0.0,338.41,9/13/2021,Rem US South Central SMM Food,129
783
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.9340931615460852,374.323,9/18/2023,Rem US South Central SMM Food,130
784
+ 0.0,0.0,0.0,0.24366733338763769,0.0,0.0,0.0,410.27,9/19/2022,Rem US South Central SMM Food,131
785
+ 0.0,0.0,0.0,0.0,0.023312915388960728,0.0,0.0,322.93,9/20/2021,Rem US South Central SMM Food,132
786
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.8875123885034688,376.732,9/25/2023,Rem US South Central SMM Food,133
787
+ 0.0,0.0,0.0,0.2768828031055804,0.0,0.0,0.0,415.53,9/26/2022,Rem US South Central SMM Food,134
788
+ 0.0,0.0,0.0,0.0,0.021042799453873943,0.0,0.0,312.75,9/27/2021,Rem US South Central SMM Food,135
789
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.7715559960356789,385.963,9/4/2023,Rem US South Central SMM Food,136
790
+ 0.0,0.0,0.0,0.24456430760086398,0.0,0.0,0.0,384.02,9/5/2022,Rem US South Central SMM Food,137
791
+ 0.0,0.0,0.0,0.0,0.021850639075460684,0.0,0.0,348.91,9/6/2021,Rem US South Central SMM Food,138
792
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4821605550049554,81.439,8/7/2023,Rem US West North Central SMM Food,124
793
+ 0.0,0.005221576383686008,0.0,0.0,0.032486163159352294,0.0,0.0,85.9,8/8/2022,Rem US West North Central SMM Food,125
794
+ 0.0,0.0,0.0,0.0,0.010447481783001583,0.0,0.0,67.85,8/9/2021,Rem US West North Central SMM Food,126
795
+ 0.0,0.0,0.04495249924795993,0.0,0.0,0.32640646345165913,0.42170465807730423,81.258,9/11/2023,Rem US West North Central SMM Food,127
796
+ 0.0,0.0,0.0,0.08643118883692774,0.0,0.0,0.0,90.01,9/12/2022,Rem US West North Central SMM Food,128
797
+ 0.0,0.0,0.0,0.0,0.006995915865349195,0.0,0.0,80.77,9/13/2021,Rem US West North Central SMM Food,129
798
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4405351833498513,77.838,9/18/2023,Rem US West North Central SMM Food,130
799
+ 0.0,0.0,0.0,0.09009565954761295,0.0,0.0,0.0,77.07,9/19/2022,Rem US West North Central SMM Food,131
800
+ 0.0,0.0,0.0,0.0,0.007515506433597942,0.0,0.0,73.56,9/20/2021,Rem US West North Central SMM Food,132
801
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4400396432111001,78.46,9/25/2023,Rem US West North Central SMM Food,133
802
+ 0.0,0.0,0.0,0.10237703355668529,0.0,0.0,0.0,82.7,9/26/2022,Rem US West North Central SMM Food,134
803
+ 0.0,0.0,0.0,0.0,0.007104782460601314,0.0,0.0,74.24,9/27/2021,Rem US West North Central SMM Food,135
804
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.38503468780971256,87.813,9/4/2023,Rem US West North Central SMM Food,136
805
+ 0.0,0.0,0.0,0.09042731448975182,0.0,0.0,0.0,85.04,9/5/2022,Rem US West North Central SMM Food,137
806
+ 0.0,0.0,0.0,0.0,0.007015091231558375,0.0,0.0,87.6,9/6/2021,Rem US West North Central SMM Food,138
807
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04112983151635283,43.858,8/7/2023,Richmond/Petersburg SMM Food,124
808
+ 0.0,0.0009487736279887459,0.0,0.0,0.007115916544206644,0.0,0.0,41.87,8/8/2022,Richmond/Petersburg SMM Food,125
809
+ 0.0,0.0,0.0,0.0,0.0012606256882035066,0.0,0.0,34.56,8/9/2021,Richmond/Petersburg SMM Food,126
810
+ 0.0,0.0,0.005540418423986577,0.0,0.0,0.04781667750388989,0.03964321110009911,41.396,9/11/2023,Richmond/Petersburg SMM Food,127
811
+ 0.0,0.0,0.0,0.01266418225172223,0.0,0.0,0.0,36.0,9/12/2022,Richmond/Petersburg SMM Food,128
812
+ 0.0,0.0,0.0,0.0,0.0013101105042271969,0.0,0.0,35.96,9/13/2021,Richmond/Petersburg SMM Food,129
813
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04162537165510406,37.841,9/18/2023,Richmond/Petersburg SMM Food,130
814
+ 0.0,0.0,0.0,0.013201112554278954,0.0,0.0,0.0,34.82,9/19/2022,Richmond/Petersburg SMM Food,131
815
+ 0.0,0.0,0.0,0.0,0.00111155267993214,0.0,0.0,33.78,9/20/2021,Richmond/Petersburg SMM Food,132
816
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0421209117938553,52.209,9/25/2023,Richmond/Petersburg SMM Food,133
817
+ 0.0,0.0,0.0,0.015000619892522049,0.0,0.0,0.0,37.32,9/26/2022,Richmond/Petersburg SMM Food,134
818
+ 0.0,0.0,0.0,0.0,0.0012204192751842583,0.0,0.0,33.61,9/27/2021,Richmond/Petersburg SMM Food,135
819
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.03617443012884043,37.615,9/4/2023,Richmond/Petersburg SMM Food,136
820
+ 0.0,0.0,0.0,0.013249707732199589,0.0,0.0,0.0,38.38,9/5/2022,Richmond/Petersburg SMM Food,137
821
+ 0.0,0.0,0.0,0.0,0.0012822752952138712,0.0,0.0,47.08,9/6/2021,Richmond/Petersburg SMM Food,138
822
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11793855302279485,26.418,8/7/2023,Sacramento/Stockton/Modesto SMM Food,124
823
+ 0.0,0.0036908304998685493,0.0,0.0,0.006869111024288489,0.0,0.0,24.42,8/8/2022,Sacramento/Stockton/Modesto SMM Food,125
824
+ 0.0,0.0,0.0,0.0,0.00287321213037551,0.0,0.0,23.32,8/9/2021,Sacramento/Stockton/Modesto SMM Food,126
825
+ 0.0,0.0,0.017499367285692864,0.0,0.0,0.09899835674878281,0.08275520317145689,27.508,9/11/2023,Sacramento/Stockton/Modesto SMM Food,127
826
+ 0.0,0.0,0.0,0.029183182904838144,0.0,0.0,0.0,25.44,9/12/2022,Sacramento/Stockton/Modesto SMM Food,128
827
+ 0.0,0.0,0.0,0.0,0.0019026911761108865,0.0,0.0,24.91,9/13/2021,Sacramento/Stockton/Modesto SMM Food,129
828
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11298315163528246,22.085,9/18/2023,Sacramento/Stockton/Modesto SMM Food,130
829
+ 0.0,0.0,0.0,0.030420478364843156,0.0,0.0,0.0,24.71,9/19/2022,Sacramento/Stockton/Modesto SMM Food,131
830
+ 0.0,0.0,0.0,0.0,0.0023127965889072188,0.0,0.0,23.73,9/20/2021,Sacramento/Stockton/Modesto SMM Food,132
831
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07879088206144698,27.12,9/25/2023,Sacramento/Stockton/Modesto SMM Food,133
832
+ 0.0,0.0,0.0,0.034567240528453246,0.0,0.0,0.0,26.42,9/26/2022,Sacramento/Stockton/Modesto SMM Food,134
833
+ 0.0,0.0,0.0,0.0,0.0016187720441749643,0.0,0.0,22.87,9/27/2021,Sacramento/Stockton/Modesto SMM Food,135
834
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10257680872150644,30.477,9/4/2023,Sacramento/Stockton/Modesto SMM Food,136
835
+ 0.0,0.0,0.0,0.030532460487995166,0.0,0.0,0.0,25.38,9/5/2022,Sacramento/Stockton/Modesto SMM Food,137
836
+ 0.0,0.0,0.0,0.0,0.0018699074854951917,0.0,0.0,25.66,9/6/2021,Sacramento/Stockton/Modesto SMM Food,138
837
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13280475718533202,31.866,8/7/2023,Salt Lake City SMM Food,124
838
+ 0.0,0.0,0.0,0.0,0.005755702663755461,0.0,0.0,30.89,8/8/2022,Salt Lake City SMM Food,125
839
+ 0.0,0.0,0.0,0.0,0.002216919757861319,0.0,0.0,30.55,8/9/2021,Salt Lake City SMM Food,126
840
+ 0.0,0.0,0.0,0.0,0.0,0.0020036799212335816,0.12338949454905847,35.521,9/11/2023,Salt Lake City SMM Food,127
841
+ 0.0,0.0,0.0,0.024569078193799245,0.0,0.0,0.0,28.16,9/12/2022,Salt Lake City SMM Food,128
842
+ 0.0,0.0,0.0,0.0,0.0018668146844937111,0.0,0.0,34.69,9/13/2021,Salt Lake City SMM Food,129
843
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12091179385530228,39.734,9/18/2023,Salt Lake City SMM Food,130
844
+ 0.0,0.0,0.0,0.0256107469124291,0.0,0.0,0.0,20.08,9/19/2022,Salt Lake City SMM Food,131
845
+ 0.0,0.0,0.0,0.0,0.002090114916800613,0.0,0.0,30.04,9/20/2021,Salt Lake City SMM Food,132
846
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11446977205153618,36.76,9/25/2023,Salt Lake City SMM Food,133
847
+ 0.0,0.0,0.0,0.02910187138286449,0.0,0.0,0.0,28.2,9/26/2022,Salt Lake City SMM Food,134
848
+ 0.0,0.0,0.0,0.0,0.0013169146664304542,0.0,0.0,31.92,9/27/2021,Salt Lake City SMM Food,135
849
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12933597621407333,38.673,9/4/2023,Salt Lake City SMM Food,136
850
+ 0.0,0.0,0.0,0.025705023731608795,0.0,0.0,0.0,29.76,9/5/2022,Salt Lake City SMM Food,137
851
+ 0.0,0.0,0.0,0.0,0.0014486679890935294,0.0,0.0,30.71,9/6/2021,Salt Lake City SMM Food,138
852
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06739345887016848,27.155,8/7/2023,San Diego SMM Food,124
853
+ 0.0,0.0020376249453456933,0.0,0.0,0.006930348484117806,0.0,0.0,23.05,8/8/2022,San Diego SMM Food,125
854
+ 0.0,0.0,0.0,0.0,0.0011183568421353973,0.0,0.0,18.52,8/9/2021,San Diego SMM Food,126
855
+ 0.0,0.0,0.008977334498881523,0.0,0.0,0.06158408920762952,0.058969276511397425,31.97,9/11/2023,San Diego SMM Food,127
856
+ 0.0,0.0,0.0,0.020400456588260608,0.0,0.0,0.0,26.77,9/12/2022,San Diego SMM Food,128
857
+ 0.0,0.0,0.0,0.0,0.0014214513402804997,0.0,0.0,22.06,9/13/2021,San Diego SMM Food,129
858
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.055996035678889985,29.921,9/18/2023,San Diego SMM Food,130
859
+ 0.0,0.0,0.0,0.021265385972826126,0.0,0.0,0.0,23.46,9/19/2022,San Diego SMM Food,131
860
+ 0.0,0.0,0.0,0.0,0.0010942329943238486,0.0,0.0,18.64,9/20/2021,San Diego SMM Food,132
861
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.059960356788899896,29.193,9/25/2023,San Diego SMM Food,133
862
+ 0.0,0.0,0.0,0.02416417332539202,0.0,0.0,0.0,27.29,9/26/2022,San Diego SMM Food,134
863
+ 0.0,0.0,0.0,0.0,0.001024335691690386,0.0,0.0,21.74,9/27/2021,San Diego SMM Food,135
864
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06739345887016848,34.927,9/4/2023,San Diego SMM Food,136
865
+ 0.0,0.0,0.0,0.021343666889227886,0.0,0.0,0.0,24.65,9/5/2022,San Diego SMM Food,137
866
+ 0.0,0.0,0.0,0.0,0.0013292858704363766,0.0,0.0,22.7,9/6/2021,San Diego SMM Food,138
867
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10852329038652131,37.539,8/7/2023,San Francisco/Oakland/San Jose SMM Food,124
868
+ 0.0,0.007054716784551935,0.0,0.0,0.010025623726399625,0.0,0.0,43.76,8/8/2022,San Francisco/Oakland/San Jose SMM Food,125
869
+ 0.0,0.0,0.0,0.0,0.0026325922124603163,0.0,0.0,35.86,8/9/2021,San Francisco/Oakland/San Jose SMM Food,126
870
+ 0.0,0.0,0.03269606409616145,0.0,0.0,0.08548204542111204,0.08919722497522299,39.91,9/11/2023,San Francisco/Oakland/San Jose SMM Food,127
871
+ 0.0,0.0,0.0,0.047694445908865776,0.0,0.0,0.0,39.0,9/12/2022,San Francisco/Oakland/San Jose SMM Food,128
872
+ 0.0,0.0,0.0,0.0,0.0020171248131656697,0.0,0.0,39.68,9/13/2021,San Francisco/Oakland/San Jose SMM Food,129
873
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09712586719524281,39.834,9/18/2023,San Francisco/Oakland/San Jose SMM Food,130
874
+ 0.0,0.0,0.0,0.04971657356674364,0.0,0.0,0.0,41.01,9/19/2022,San Francisco/Oakland/San Jose SMM Food,131
875
+ 0.0,0.0,0.0,0.0,0.002183517507045328,0.0,0.0,37.16,9/20/2021,San Francisco/Oakland/San Jose SMM Food,132
876
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0817641228939544,38.973,9/25/2023,San Francisco/Oakland/San Jose SMM Food,133
877
+ 0.0,0.0,0.0,0.056493679565598955,0.0,0.0,0.0,40.14,9/26/2022,San Francisco/Oakland/San Jose SMM Food,134
878
+ 0.0,0.0,0.0,0.0,0.0021674349418376285,0.0,0.0,36.73,9/27/2021,San Francisco/Oakland/San Jose SMM Food,135
879
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09068384539147671,45.739,9/4/2023,San Francisco/Oakland/San Jose SMM Food,136
880
+ 0.0,0.0,0.0,0.049899587365703414,0.0,0.0,0.0,42.29,9/5/2022,San Francisco/Oakland/San Jose SMM Food,137
881
+ 0.0,0.0,0.0,0.0,0.0014294926228843492,0.0,0.0,39.55,9/6/2021,San Francisco/Oakland/San Jose SMM Food,138
882
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.176412289395441,54.498,8/7/2023,Seattle/Tacoma SMM Food,124
883
+ 0.0,0.006289632662621285,0.0,0.0,0.014541731748761649,0.0,0.0,38.02,8/8/2022,Seattle/Tacoma SMM Food,125
884
+ 0.0,0.0,0.0,0.0,0.0025020760101978337,0.0,0.0,44.59,8/9/2021,Seattle/Tacoma SMM Food,126
885
+ 0.0,0.0,0.04408198262886745,0.0,0.0,0.13501876631890186,0.14073339940535184,56.797,9/11/2023,Seattle/Tacoma SMM Food,127
886
+ 0.0,0.0,0.0,0.03795459470136038,0.0,0.0,0.0,45.0,9/12/2022,Seattle/Tacoma SMM Food,128
887
+ 0.0,0.0,0.0,0.0,0.0019701142379431645,0.0,0.0,47.26,9/13/2021,Seattle/Tacoma SMM Food,129
888
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15163528245787908,53.988,9/18/2023,Seattle/Tacoma SMM Food,130
889
+ 0.0,0.0,0.0,0.03956377652701973,0.0,0.0,0.0,42.63,9/19/2022,Seattle/Tacoma SMM Food,131
890
+ 0.0,0.0,0.0,0.0,0.0010663977853105227,0.0,0.0,44.68,9/20/2021,Seattle/Tacoma SMM Food,132
891
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14767096134786917,57.516,9/25/2023,Seattle/Tacoma SMM Food,133
892
+ 0.0,0.0,0.0,0.04495690578008078,0.0,0.0,0.0,43.4,9/26/2022,Seattle/Tacoma SMM Food,134
893
+ 0.0,0.0,0.0,0.0,0.002235476563870203,0.0,0.0,47.9,9/27/2021,Seattle/Tacoma SMM Food,135
894
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13429137760158572,69.688,9/4/2023,Seattle/Tacoma SMM Food,136
895
+ 0.0,0.0,0.0,0.039709416436374406,0.0,0.0,0.0,41.17,9/5/2022,Seattle/Tacoma SMM Food,137
896
+ 0.0,0.0,0.0,0.0,0.0016051637197684492,0.0,0.0,42.94,9/6/2021,Seattle/Tacoma SMM Food,138
897
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13875123885034688,41.124,8/7/2023,St. Louis SMM Food,124
898
+ 0.0,0.0016459850550708866,0.0,0.0,0.010519234766235935,0.0,0.0,33.68,8/8/2022,St. Louis SMM Food,125
899
+ 0.0,0.0,0.0,0.0,0.0028880575751826162,0.0,0.0,35.24,8/9/2021,St. Louis SMM Food,126
900
+ 0.0,0.0,0.013647236303775618,0.0,0.0,0.11378140992305427,0.09266600594648167,41.021,9/11/2023,St. Louis SMM Food,127
901
+ 0.0,0.0,0.0,0.028725686548902455,0.0,0.0,0.0,46.76,9/12/2022,St. Louis SMM Food,128
902
+ 0.0,0.0,0.0,0.0,0.002591148679040476,0.0,0.0,37.37,9/13/2021,St. Louis SMM Food,129
903
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09266600594648167,38.672,9/18/2023,St. Louis SMM Food,130
904
+ 0.0,0.0,0.0,0.029943585281161426,0.0,0.0,0.0,41.99,9/19/2022,St. Louis SMM Food,131
905
+ 0.0,0.0,0.0,0.0,0.0026987781538920018,0.0,0.0,33.82,9/20/2021,St. Louis SMM Food,132
906
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09217046580773042,52.498,9/25/2023,St. Louis SMM Food,133
907
+ 0.0,0.0,0.0,0.034025339850661744,0.0,0.0,0.0,38.58,9/26/2022,St. Louis SMM Food,134
908
+ 0.0,0.0,0.0,0.0,0.003129296053298106,0.0,0.0,35.39,9/27/2021,St. Louis SMM Food,135
909
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09514370664023786,44.922,9/4/2023,St. Louis SMM Food,136
910
+ 0.0,0.0,0.0,0.03005381188828102,0.0,0.0,0.0,51.7,9/5/2022,St. Louis SMM Food,137
911
+ 0.0,0.0,0.0,0.0,0.0020622797077872873,0.0,0.0,45.12,9/6/2021,St. Louis SMM Food,138
912
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.18434093161546083,392.534,8/7/2023,Tampa/Ft. Myers SMM Food,124
913
+ 0.0,0.002718951273633502,0.0,0.0,0.014108739608554358,0.0,0.0,249.67,8/8/2022,Tampa/Ft. Myers SMM Food,125
914
+ 0.0,0.0,0.0,0.0,0.005458175207413023,0.0,0.0,94.56,8/9/2021,Tampa/Ft. Myers SMM Food,126
915
+ 0.0,0.0,0.018081680874809502,0.0,0.0,0.19101996581778166,0.1377601585728444,112.223,9/11/2023,Tampa/Ft. Myers SMM Food,127
916
+ 0.0,0.0,0.0,0.05247086431152936,0.0,0.0,0.0,92.25,9/12/2022,Tampa/Ft. Myers SMM Food,128
917
+ 0.0,0.0,0.0,0.0,0.004128889336976647,0.0,0.0,93.22,9/13/2021,Tampa/Ft. Myers SMM Food,129
918
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13181367690782952,105.58,9/18/2023,Tampa/Ft. Myers SMM Food,130
919
+ 0.0,0.0,0.0,0.05469550040636205,0.0,0.0,0.0,85.97,9/19/2022,Tampa/Ft. Myers SMM Food,131
920
+ 0.0,0.0,0.0,0.0,0.004280436586049198,0.0,0.0,86.54,9/20/2021,Tampa/Ft. Myers SMM Food,132
921
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13875123885034688,98.576,9/25/2023,Tampa/Ft. Myers SMM Food,133
922
+ 0.0,0.0,0.0,0.062151307947871305,0.0,0.0,0.0,92.27,9/26/2022,Tampa/Ft. Myers SMM Food,134
923
+ 0.0,0.0,0.0,0.0,0.004065796196546442,0.0,0.0,83.16,9/27/2021,Tampa/Ft. Myers SMM Food,135
924
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.18533201189296333,155.563,9/4/2023,Tampa/Ft. Myers SMM Food,136
925
+ 0.0,0.0,0.0,0.0548968423482816,0.0,0.0,0.0,131.88,9/5/2022,Tampa/Ft. Myers SMM Food,137
926
+ 0.0,0.0,0.0,0.0,0.004370127815092137,0.0,0.0,85.36,9/6/2021,Tampa/Ft. Myers SMM Food,138
927
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.033201189296333006,14.745,8/7/2023,Tucson/Sierra Vista SMM Food,124
928
+ 0.0,0.0008540406751789106,0.0,0.0,0.0032796061819700653,0.0,0.0,11.07,8/8/2022,Tucson/Sierra Vista SMM Food,125
929
+ 0.0,0.0,0.0,0.0,0.0014684619155030051,0.0,0.0,10.23,8/9/2021,Tucson/Sierra Vista SMM Food,126
930
+ 0.0,0.0,0.004325155281482285,0.0,0.0,0.03514997428852929,0.033201189296333006,13.086,9/11/2023,Tucson/Sierra Vista SMM Food,127
931
+ 0.0,0.0,0.0,0.008438669343202216,0.0,0.0,0.0,15.07,9/12/2022,Tucson/Sierra Vista SMM Food,128
932
+ 0.0,0.0,0.0,0.0,0.0005659825832709562,0.0,0.0,12.89,9/13/2021,Tucson/Sierra Vista SMM Food,129
933
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04558969276511397,13.845,9/18/2023,Tucson/Sierra Vista SMM Food,130
934
+ 0.0,0.0,0.0,0.008796448244863359,0.0,0.0,0.0,12.4,9/19/2022,Tucson/Sierra Vista SMM Food,131
935
+ 0.0,0.0,0.0,0.0,0.0005641269026700677,0.0,0.0,11.2,9/20/2021,Tucson/Sierra Vista SMM Food,132
936
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.028741328047571853,14.286,9/25/2023,Tucson/Sierra Vista SMM Food,133
937
+ 0.0,0.0,0.0,0.009995534545410896,0.0,0.0,0.0,14.46,9/26/2022,Tucson/Sierra Vista SMM Food,134
938
+ 0.0,0.0,0.0,0.0,0.0005597969812679949,0.0,0.0,13.72,9/27/2021,Tucson/Sierra Vista SMM Food,135
939
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.036669970267591674,14.191,9/4/2023,Tucson/Sierra Vista SMM Food,136
940
+ 0.0,0.0,0.0,0.008828829229391247,0.0,0.0,0.0,13.52,9/5/2022,Tucson/Sierra Vista SMM Food,137
941
+ 0.0,0.0,0.0,0.0,0.0008028911399843727,0.0,0.0,12.27,9/6/2021,Tucson/Sierra Vista SMM Food,138
942
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17443012884043607,117.859,8/7/2023,Washington DC/Hagerstown SMM Food,124
943
+ 0.0,0.008450294918628531,0.0,0.0,0.01769886301107308,0.0,0.0,121.38,8/8/2022,Washington DC/Hagerstown SMM Food,125
944
+ 0.0,0.0,0.0,0.0,0.005262091623919152,0.0,0.0,114.34,8/9/2021,Washington DC/Hagerstown SMM Food,126
945
+ 0.0,0.0,0.05609156745484475,0.0,0.0,0.19144403459184595,0.155599603567889,160.362,9/11/2023,Washington DC/Hagerstown SMM Food,127
946
+ 0.0,0.0,0.0,0.05177122745529417,0.0,0.0,0.0,144.07,9/12/2022,Washington DC/Hagerstown SMM Food,128
947
+ 0.0,0.0,0.0,0.0,0.0036185771717323423,0.0,0.0,123.88,9/13/2021,Washington DC/Hagerstown SMM Food,129
948
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14519326065411298,165.895,9/18/2023,Washington DC/Hagerstown SMM Food,130
949
+ 0.0,0.0,0.0,0.05396620066002498,0.0,0.0,0.0,138.59,9/19/2022,Washington DC/Hagerstown SMM Food,131
950
+ 0.0,0.0,0.0,0.0,0.0035734222771107256,0.0,0.0,116.24,9/20/2021,Washington DC/Hagerstown SMM Food,132
951
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1620416253716551,159.074,9/25/2023,Washington DC/Hagerstown SMM Food,133
952
+ 0.0,0.0,0.0,0.06132259383502524,0.0,0.0,0.0,132.64,9/26/2022,Washington DC/Hagerstown SMM Food,134
953
+ 0.0,0.0,0.0,0.0,0.002285579940094189,0.0,0.0,113.16,9/27/2021,Washington DC/Hagerstown SMM Food,135
954
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1337958374628345,117.933,9/4/2023,Washington DC/Hagerstown SMM Food,136
955
+ 0.0,0.0,0.0,0.054164857947246375,0.0,0.0,0.0,118.44,9/5/2022,Washington DC/Hagerstown SMM Food,137
956
+ 0.0,0.0,0.0,0.0,0.0032740391401673997,0.0,0.0,130.79,9/6/2021,Washington DC/Hagerstown SMM Food,138
957
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.024281466798810703,3.773,8/7/2023,Yakima/Pasco/Richland/Kennewick SMM Food,124
958
+ 0.0,0.00041792250827997425,0.0,0.0,0.0016707311009998389,0.0,0.0,3.86,8/8/2022,Yakima/Pasco/Richland/Kennewick SMM Food,125
959
+ 0.0,0.0,0.0,0.0,0.00020907334770009088,0.0,0.0,3.64,8/9/2021,Yakima/Pasco/Richland/Kennewick SMM Food,126
960
+ 0.0,0.0,0.0024254626885814802,0.0,0.0,0.023424539263820505,0.022794846382556987,4.202,9/11/2023,Yakima/Pasco/Richland/Kennewick SMM Food,127
961
+ 0.0,0.0,0.0,0.0051309930988511126,0.0,0.0,0.0,3.78,9/12/2022,Yakima/Pasco/Richland/Kennewick SMM Food,128
962
+ 0.0,0.0,0.0,0.0,0.00041010541279633213,0.0,0.0,3.71,9/13/2021,Yakima/Pasco/Richland/Kennewick SMM Food,129
963
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.018334985133795837,4.43,9/18/2023,Yakima/Pasco/Richland/Kennewick SMM Food,130
964
+ 0.0,0.0,0.0,0.005348534635223674,0.0,0.0,0.0,3.76,9/19/2022,Yakima/Pasco/Richland/Kennewick SMM Food,131
965
+ 0.0,0.0,0.0,0.0,0.0005270132906523001,0.0,0.0,3.12,9/20/2021,Yakima/Pasco/Richland/Kennewick SMM Food,132
966
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.02180376610505451,3.573,9/25/2023,Yakima/Pasco/Richland/Kennewick SMM Food,133
967
+ 0.0,0.0,0.0,0.006077619195352498,0.0,0.0,0.0,2.75,9/26/2022,Yakima/Pasco/Richland/Kennewick SMM Food,134
968
+ 0.0,0.0,0.0,0.0,0.000404538370993667,0.0,0.0,3.74,9/27/2021,Yakima/Pasco/Richland/Kennewick SMM Food,135
969
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.015857284440039643,4.901,9/4/2023,Yakima/Pasco/Richland/Kennewick SMM Food,136
970
+ 0.0,0.0,0.0,0.005368223354373092,0.0,0.0,0.0,3.93,9/5/2022,Yakima/Pasco/Richland/Kennewick SMM Food,137
971
+ 0.0,0.0,0.0,0.0,0.0004614459094209107,0.0,0.0,3.81,9/6/2021,Yakima/Pasco/Richland/Kennewick SMM Food,138
Test/X_train_test_tuned_trend.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/X_train_tuned_trend.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/merged_df_contri.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/output_df.csv ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,const,BroadcastTV,CableTV,Connected&OTTTV,DisplayProspecting,DisplayRetargeting, Video,SocialProspecting,SocialRetargeting,SearchBrand,SearchNon-brand,DigitalPartners,Audio,Email
2
+ 2022-02-27,1,605.7688941,880.7115151,135.0516981,208.2711327,19.41746001,297.0007496,345.010799,51.00935797,214.3019417,892.607461,833.4551364,316.7036224,0.0
3
+ 2022-03-06,1,779.587861,837.4491512,157.5004969,207.4753074,79.15177069,392.480332,343.428751,50.4354065,219.5135831,875.611235,819.5548137,315.3451715,0.0
4
+ 2022-03-13,1,864.7806971,954.5658374,187.947124,221.713362,76.2604722,468.6212166,366.996612,67.83612655,234.9089159,901.5223839,875.796913,336.9854082,0.0
5
+ 2022-03-20,1,731.3285906,936.5859186,196.7562215,227.2802865,62.379592,339.6859962,376.2114027,82.22335436,240.9831858,932.7780942,897.7869942,345.4468683,0.0
6
+ 2022-03-27,1,686.1206578,918.340495,209.7801073,208.7921837,27.39101731,164.8588646,345.6085063,79.3408774,221.3853364,991.6264718,789.6958012,317.3467101,0.0
7
+ 2022-04-03,1,690.8365006,809.1925488,228.8269719,180.9403061,22.82948094,190.2177151,299.5059862,53.00895811,191.8827057,1098.987071,605.7673405,275.0141765,0.0
8
+ 2022-04-10,1,720.8362641,735.4593072,225.7303976,173.9216886,24.71429802,139.7027908,287.8882436,44.87884693,184.4272411,984.3838731,582.2698163,264.3464426,0.0
9
+ 2022-04-17,1,775.4075191,796.3286979,227.1361474,184.1782682,20.09658828,185.1578527,304.8657049,49.54791165,195.3077905,992.5354147,616.6076663,279.9348206,0.0
10
+ 2022-04-24,1,835.5742747,795.138986,203.775006,194.3528204,30.77660161,197.2930056,321.7073877,54.16304355,206.1241222,1127.671193,650.6708965,295.3997591,0.0
11
+ 2022-05-01,1,778.4072046,800.3858887,209.6706691,187.8029139,14.68086209,117.0588368,310.8654904,48.92250172,199.1598609,1522.512401,573.2443965,285.4445468,0.0
12
+ 2022-05-08,1,888.1079123,918.5182742,230.406251,207.458539,6.824600634,105.0858789,343.4009675,57.14979371,220.0015126,1502.533433,633.2406986,315.3190743,0.0
13
+ 2022-05-15,1,942.8699373,927.5320449,231.7409952,219.2881419,5.789528794,103.0402573,362.9822054,58.18594974,232.5560247,1604.383918,669.3490323,333.2967868,0.0
14
+ 2022-05-22,1,885.4667828,886.484453,205.2506739,206.7666081,10.84383167,60.95975874,342.2556214,44.88531703,219.249405,1285.973994,631.1286493,314.2363601,0.0
15
+ 2022-05-29,1,872.1263477,819.8747129,211.6585103,203.0097861,32.79210764,170.5377143,336.0370474,32.71797255,215.2991394,1159.99767,590.7548479,308.5578319,0.0
16
+ 2022-06-05,1,850.0419903,833.2096897,239.4503592,196.9778946,30.43141305,86.116707,326.0526075,33.33021252,208.8987866,1289.817117,551.8094443,299.3899667,0.0
17
+ 2022-06-12,1,899.3901532,898.3532455,305.2964146,208.0552874,37.41568812,114.7826432,344.3887402,41.13349708,220.6385363,1252.42105,582.8414035,316.2265328,0.0
18
+ 2022-06-19,1,890.7498196,863.113055,347.5208084,211.5952537,44.94118232,180.9492415,350.2483583,53.12879903,224.3962372,1261.189978,592.7581854,321.6060907,0.0
19
+ 2022-06-26,1,783.8586228,851.2196504,300.3451176,203.3583296,28.70458021,125.5195234,336.6139827,78.56584301,215.605161,1234.200295,562.5795688,309.0877084,0.0
20
+ 2022-07-03,1,623.6384606,840.8641099,324.3629383,202.3052943,240.2171456,95.76678262,334.8709197,127.4832436,214.5120877,1204.274958,541.8456282,307.4871828,0.0
21
+ 2022-07-10,1,570.9534282,810.5012067,310.9911019,190.8623186,400.769678,57.01233229,315.9296467,108.8375367,202.3840169,1278.989752,511.1972638,290.0948136,0.0
22
+ 2022-07-17,1,565.9144673,868.0299469,301.9873788,202.0068077,507.6894432,157.6772267,334.3768422,135.0554174,214.2630912,1330.862763,541.0461746,307.033508,0.0
23
+ 2022-07-24,1,776.477908,825.4595302,271.5249881,194.6964057,619.1057667,260.0666358,322.2761157,125.3193069,206.5089226,1452.799799,521.4663146,295.9223064,0.0
24
+ 2022-07-31,1,785.3267172,962.6372069,345.4081407,224.2156499,238.5261414,274.3828509,371.1385861,101.5508396,237.8202057,1251.893504,603.1063041,340.7890968,0.0
25
+ 2022-08-07,1,986.8501755,1025.938955,422.6665647,235.7866071,209.0412688,410.6777854,390.2917036,119.4059165,250.1011998,1417.025462,634.6816576,358.3759871,0.0
26
+ 2022-08-14,1,1006.21652,1142.638552,486.4307695,261.8529063,192.5468754,340.7100759,433.4386,135.4558489,277.7534112,1605.035096,704.8459564,397.9945889,103.920732
27
+ 2022-08-21,1,1045.876273,1071.63155,428.4331739,246.2402262,154.138197,297.8833874,407.5953191,106.1105392,261.1953233,1440.538398,662.8203223,374.2646167,109.3511473
28
+ 2022-08-28,1,924.8436782,982.0672117,380.9582995,222.7309308,62.13676538,205.2154934,368.6809675,108.0664987,236.2580181,2029.075506,595.3198181,338.5324475,109.4662867
29
+ 2022-09-04,1,904.0255621,940.8469486,375.9460785,211.9111493,622.9329915,322.1537139,350.7712524,114.4929439,224.7751952,1238.898241,561.0313292,322.0872816,96.31021073
30
+ 2022-09-11,1,774.0487128,958.7032872,367.374283,216.6169201,911.1160082,304.1690603,358.5605977,102.2195552,229.7675513,1270.879978,573.489781,329.2396609,44.65132361
31
+ 2022-09-18,1,764.4287881,975.7007039,410.3422984,220.4645506,714.4632252,582.8133759,364.9294848,94.58256909,233.8420917,1181.854654,583.6763205,335.0877386,18.13472182
32
+ 2022-09-25,1,923.7236418,960.6266038,331.1681887,217.0223981,717.9420235,414.3210787,359.2317754,77.51748351,230.1648921,1084.965103,596.039424,329.8559537,6.750685498
33
+ 2022-10-02,1,882.1976889,905.1478389,277.5831914,205.8992085,219.2100648,653.009739,340.8198365,79.39525999,218.36179,1299.117345,682.3431097,312.9496328,2.372080109
34
+ 2022-10-09,1,925.6915886,937.4895649,271.0318506,214.0389525,175.4585553,278.0199444,354.2933522,75.45880964,227.0165089,988.3326224,709.3179502,325.3213651,0.906191227
35
+ 2022-10-16,1,959.015952,941.7629421,258.9467906,221.7055116,177.3128816,249.2487123,366.9836166,82.21692268,235.1651607,921.5401156,734.7246713,336.9738958,0.343961469
36
+ 2022-10-23,1,930.856466,920.413168,222.6284273,215.216801,146.6142957,236.4479192,356.2430154,101.3337553,228.2855523,1082.155704,713.2213007,327.1115966,0.122224575
37
+ 2022-10-30,1,875.7574588,870.6189769,283.5774898,208.1475282,100.8371491,298.5716442,344.541424,79.49592653,220.7864015,960.6661455,587.678263,316.3668912,0.043254893
38
+ 2022-11-06,1,803.6846058,783.0789848,281.3661876,197.9310933,176.2377577,304.2184505,327.6304136,68.92122227,209.9334426,1108.999284,518.1268808,300.8387619,0.015048678
39
+ 2022-11-13,1,647.9625567,770.970499,272.4051279,196.0453894,157.6398366,397.0884418,324.5090549,61.72397847,207.9374168,1290.391574,513.1906484,297.9726492,0.005453042
40
+ 2022-11-20,1,410.51923,875.5737551,287.1069279,230.3808944,45.10005665,312.228454,381.3437619,51.98679658,244.3474116,792.170016,603.0711608,350.1597544,0.002344328
41
+ 2022-11-27,1,515.4365373,871.8631846,348.7779578,224.0776323,67.21391461,251.8782636,370.910129,50.54907139,237.6791529,743.5466564,535.9685021,340.5793215,0.000834175
42
+ 2022-12-04,1,775.9431065,751.9638968,317.0579992,199.2553527,76.69204679,291.5840329,329.8224272,34.05423057,211.3571157,873.0841132,413.9884868,302.8515258,0.000271365
43
+ 2022-12-11,1,709.4923926,717.6125648,297.7512423,186.0748608,149.878576,285.1416859,308.0050869,27.63572864,197.3693186,1228.057409,386.6036669,282.8182768,9.27e-05
44
+ 2022-12-18,1,756.3419366,722.0103794,287.4807103,189.5386168,134.5352621,220.7993168,313.738556,38.40880097,200.852912,1514.734677,393.8002369,288.0828972,3.45e-05
45
+ 2022-12-25,1,921.0774008,925.2288971,355.9887642,218.1475832,301.3272623,337.3294677,361.0942662,84.56738121,230.6153342,1892.842275,453.2404604,331.5661412,1.45e-05
46
+ 2023-01-01,1,941.8367772,960.9193838,366.8490383,217.6573364,593.495164,303.9119076,360.2827729,134.6944234,230.8385562,2236.397692,772.0546998,330.821007,70.35472737
47
+ 2023-01-08,1,954.6035992,988.370554,396.9060203,220.6044148,459.1720798,336.3753656,365.1609984,121.7401462,234.0029461,1867.924583,782.5083143,335.3003204,85.80654375
48
+ 2023-01-15,1,996.848517,1036.093236,409.8730378,230.3670254,384.7798026,396.3042818,381.3208049,128.4545641,244.3589615,1781.92823,817.1373766,350.1386748,94.62078669
49
+ 2023-01-22,1,907.6599112,944.9691158,346.3453952,209.7559482,250.1273413,513.5127134,347.2038016,130.5022088,222.4961142,1511.331964,744.0276007,318.8115555,84.09824673
50
+ 2023-01-29,1,774.3921141,800.7599363,284.0726168,178.9583884,259.7907908,402.1916991,296.2253672,89.92870532,189.8279431,1356.106132,566.1600024,272.0018314,57.09380571
51
+ 2023-02-05,1,738.2279086,756.6310299,273.7329359,170.6042753,249.3785662,381.535779,282.3970118,63.15497073,180.9661297,1281.839882,488.5086031,259.3042766,22.92877821
52
+ 2023-02-12,1,806.3032314,823.2695123,290.3194022,186.5988167,193.7645359,354.3389573,308.8723781,46.00288315,197.9323395,1141.09809,534.3074029,283.6146461,9.694651036
53
+ 2023-02-19,1,811.9837253,847.926579,288.9377253,192.5718806,148.356776,327.361602,318.7594422,42.54824661,204.2684901,1112.283767,551.4106852,292.6932053,3.736745996
54
+ 2023-02-26,1,841.0340117,874.3566114,268.0186306,200.5740943,215.6890987,365.3412053,332.0053074,45.39907457,212.7567766,1219.472684,558.0137595,304.8559031,1.434771732
55
+ 2023-03-05,1,855.428122,865.155276,254.0903056,200.9145857,157.8896583,371.8603531,332.5689143,47.57359868,213.1179496,1204.589183,546.5852641,305.3733122,0.527259313
56
+ 2023-03-12,1,787.9587837,836.3060115,234.3598207,195.2757268,157.6073414,373.3335881,323.2350515,40.47258073,207.136592,1284.306192,531.244829,296.8017638,0.187669152
57
+ 2023-03-19,1,709.4342034,817.521727,217.9477557,192.0499114,169.4410563,356.1987464,317.8954395,43.24769286,203.7148436,1242.126802,522.4690441,291.877999,0.067547188
58
+ 2023-03-26,1,688.4936049,766.7113114,167.9836758,184.2114826,194.3286576,292.2202432,304.9206833,44.33831994,195.4003159,1087.191512,496.772508,279.9806566,0.023705804
59
+ 2023-04-02,1,648.4127851,709.374272,379.7574522,172.9962403,123.0072906,296.386829,286.3563718,25.01102175,183.5038702,1109.919508,441.5925556,262.9361771,0.008144821
60
+ 2023-04-09,1,636.8844453,636.0402807,370.8363713,154.8687069,375.6187651,277.765361,256.3503169,19.63808085,164.2752875,977.430835,395.3199674,235.3690974,0.002667482
61
+ 2023-04-16,1,643.202747,697.9311949,400.1671801,169.0921007,303.9842128,288.5176945,279.8939469,26.0160255,179.362597,999.7052811,431.6267961,256.9079406,0.001065489
62
+ 2023-04-23,1,680.2328465,768.0223303,428.1466005,185.2406354,369.5169101,285.729516,306.6242236,25.94739503,196.4919844,1082.094568,472.8477793,280.8264039,0.00042702
63
+ 2023-04-30,1,757.8051683,805.1918653,568.5505022,191.6262435,177.0239561,342.9543489,317.194154,25.48726963,203.2654434,1077.23059,519.6833732,291.2532891,76.08094879
64
+ 2023-05-07,1,816.8896164,809.7824501,623.0873893,193.3403495,132.8104708,432.388876,320.0314696,25.5940547,205.0836617,1114.644548,529.3989259,293.8598601,65.16989915
65
+ 2023-05-14,1,846.3276207,871.5314255,650.3059216,206.9104899,120.1442642,284.4808969,342.4937854,26.57100509,219.4780398,1124.917313,566.5562901,314.4755735,42.71769839
66
+ 2023-05-21,1,742.3856418,860.1913668,534.25428,204.0773489,76.52708573,250.7751673,337.8041576,33.16461757,216.4728164,1153.774175,558.7986658,309.9620644,39.4479893
67
+ 2023-05-28,1,685.9715645,854.9860127,419.3190634,211.2394701,56.89628875,237.4167674,349.6594386,30.06195147,224.0699582,1257.584361,574.2115765,320.9980289,40.58729967
68
+ 2023-06-04,1,659.741062,815.6101963,262.1682047,200.0668991,127.797631,483.0461649,331.1657597,27.1864638,212.2187756,1081.350495,538.5222072,304.0791733,38.42146311
69
+ 2023-06-11,1,626.4784725,774.5792218,209.65455,191.0967281,148.6190586,460.9364201,316.317659,28.18699555,202.7037649,1048.60873,514.3771024,290.4383861,36.6973037
70
+ 2023-06-18,1,638.0935884,776.2166825,193.4182543,192.1920365,148.6214006,430.1358818,318.1306957,23.94794524,203.8656012,867.7902211,517.3253556,292.0209331,36.90751782
71
+ 2023-06-25,1,615.7519552,779.0937361,175.7288582,188.932373,174.7887979,341.5503578,312.7350559,24.54955316,200.4079488,836.245072,514.770607,286.9062403,36.28153974
72
+ 2023-07-02,1,621.2794795,764.9240996,174.1094132,194.5021389,325.8319993,471.0434465,321.9545507,36.67334949,206.3160171,785.0143666,567.758123,295.5412035,37.35112627
73
+ 2023-07-09,1,580.9318638,760.7512215,160.1609936,189.3726234,286.0264842,556.4721175,313.4637914,34.28548491,200.8749396,985.469408,552.7848992,287.6860648,36.36608213
74
+ 2023-07-16,1,691.0363912,729.0096528,172.3823025,170.2445186,337.2839681,652.624446,281.8015154,25.51385772,180.5850116,1625.024876,496.9493337,258.4400254,32.69282556
75
+ 2023-07-23,1,687.8649333,893.0019017,244.0713041,203.3442754,372.0055376,527.8809181,336.5907193,34.34863145,215.6952167,1592.53979,593.5686097,307.4307526,39.0491217
76
+ 2023-07-30,1,543.4952059,925.5413754,306.0685377,210.6151761,546.8054746,544.1495942,348.6260603,31.05021476,223.4077451,1544.034657,628.1932532,320.1174898,40.44538568
77
+ 2023-08-06,1,621.9390612,969.2205314,326.5280836,221.6818558,519.0192833,226.46071,366.9444598,35.7977093,235.1466046,1757.373196,666.8102041,336.937941,42.57057027
78
+ 2023-08-13,1,628.9128166,1014.287182,326.0213373,231.8445167,602.0250578,230.9748621,383.7664595,41.77518663,245.926536,1682.047707,697.3790839,352.3843384,100.8056128
79
+ 2023-08-20,1,335.2835947,967.1172924,311.8617942,221.3894094,400.6572593,138.0241161,366.4603804,47.34643425,234.8363952,2270.35583,665.9305368,336.4934467,119.951625
80
+ 2023-08-27,1,516.0096306,1052.901423,291.3082569,239.4361589,385.581239,133.5620316,396.3327159,42.79171664,253.9792874,1760.723528,680.3115125,363.9228016,132.6774217
81
+ 2023-09-03,1,425.218926,907.3804626,232.4505875,204.0199436,241.6556935,95.21978422,337.709136,23.15806633,216.4119243,2604.193939,491.0303535,310.0921179,100.0283307
82
+ 2023-09-10,1,548.9105155,831.4659197,253.1288112,186.4398897,168.5357607,96.55435719,308.6093103,16.30543897,197.7640744,2650.370027,448.7190973,283.371267,42.36547919
83
+ 2023-09-17,1,446.710714,780.6749097,237.2757502,175.0754168,132.8388084,150.8661646,289.797981,12.31574625,185.709334,2874.469183,421.3673538,266.0610285,16.03044292
84
+ 2023-09-24,1,560.6133792,920.1635269,244.8992536,209.1039271,131.297661,207.1889954,346.1245273,12.7478761,221.8047042,1705.547661,503.2663639,317.8205296,7.268312037
85
+ 2023-10-01,1,678.3406906,944.4331704,226.8916795,217.8674745,94.41199605,185.0175423,360.6306093,7.842450148,231.1005413,1791.039282,497.2463016,331.1403988,2.808861543
86
+ 2023-10-08,1,763.9269378,906.1479737,207.8916876,211.168603,92.25577093,191.036741,349.542134,6.773499719,223.9947866,1500.683497,481.9572407,320.9586728,1.001048031
87
+ 2023-10-15,1,814.021625,867.0010643,193.496147,203.0211766,74.29807486,181.8273082,336.0559018,7.487252365,215.3524932,1595.030622,463.3620941,308.5752506,83.28439757
88
+ 2023-10-22,1,887.494946,890.435337,194.4830652,210.1274647,67.4865255,162.9667114,347.8187636,8.764300735,222.8904105,1777.06454,479.5810155,319.3751355,58.98317443
89
+ 2023-10-29,1,981.0546288,932.5152103,284.8555313,227.94298,90.0912389,190.2309151,377.3083429,8.880990517,241.7880237,1088.380818,479.6898561,346.4543277,26.44608201
90
+ 2023-11-05,1,943.6225993,880.2052338,283.417584,218.2384532,73.76391771,189.9813722,361.2446811,8.617717067,231.4940529,773.8454245,429.3467486,331.7042561,9.711508801
91
+ 2023-11-12,1,859.9426368,784.7082927,268.7375762,198.7428744,52.96298974,155.7534535,328.9741347,8.086477292,210.8143309,843.1577668,390.992539,302.0726015,3.293174362
92
+ 2023-11-19,1,841.5834198,761.789057,267.9687151,194.4867235,47.90933731,136.5205807,321.929034,6.759498821,206.2996654,655.4502986,382.6192916,295.6036069,1.18667682
93
+ 2023-11-26,1,810.4858422,750.223927,218.9064763,187.2994981,38.94589943,119.5074091,310.0321989,4.790676071,198.6758948,934.3953915,374.4267708,284.6796236,0.419087036
94
+ 2023-12-03,1,794.1794746,739.8412707,197.3078416,183.5311519,59.25797091,138.3346547,303.7945489,4.317132205,194.6786626,999.79707,381.3186586,278.9520513,0.150363814
95
+ 2023-12-10,1,799.0346099,751.2994538,185.4197449,184.6531506,39.08780584,133.8354685,305.6517654,4.522006415,195.8688104,932.1781895,383.6498107,280.6566165,0.055362369
96
+ 2023-12-17,1,740.9191363,707.0078691,165.898516,171.2229372,30.97593247,126.4293179,283.4210673,4.152010161,181.6228584,1382.04466,355.7461502,260.2234982,0.018782607
97
+ 2023-12-24,1,771.1616752,794.0299265,166.834395,178.2118461,52.33955324,190.8943106,294.9896343,16.1961226,189.0362671,1377.89555,370.2668533,270.7619601,61.54687964
98
+ 2023-12-31,1,902.4842186,944.0734789,342.6691304,208.5598699,74.90915424,268.009429,345.223963,49.28293154,221.2276015,1673.222589,436.4837233,316.9936163,86.29973693
99
+ 2024-01-07,1,886.1177399,925.4876581,399.2989247,204.7776534,100.4824572,253.4924168,338.9633542,57.15484452,217.2156567,2438.813385,429.0850088,311.2449625,93.51421135
100
+ 2024-01-14,1,930.9929903,975.8722935,418.1218049,215.1481133,92.07061249,317.3728997,356.1293184,58.26787291,228.2160087,2356.367813,450.8149622,327.0071971,101.2048688
101
+ 2024-01-21,1,944.7091262,991.9503913,404.4381143,218.317848,97.06020522,285.3321032,361.3761013,63.32363006,231.5782701,2132.63934,457.45673,331.8249295,80.39592249
102
+ 2024-01-28,1,756.8327128,796.77418,291.755412,174.900493,62.45330919,183.3266773,289.5084339,34.6330342,185.5237855,2403.826128,374.5639516,265.8341692,62.15022457
103
+ 2024-02-04,1,678.2223822,706.1173784,247.9555963,156.7341714,48.12657472,123.9688776,259.4381739,13.7724102,166.2540585,1910.152171,345.2289379,238.2228749,23.90546722
104
+ 2024-02-11,1,698.2864765,717.9268176,249.9909147,161.4955493,45.71740336,113.8285012,267.3195642,13.13273961,171.304638,1352.231509,355.7165388,245.4597723,9.597072979
105
+ 2024-02-18,1,697.868311,716.6343822,263.1942582,161.5547736,41.50723114,112.8980681,267.4175967,12.93070055,171.3674596,1243.833141,355.8469885,245.5497883,3.596622212
Test/scenario_test_df.csv ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ other_contributions,correction,sales
2
+ 1,-890.9083269913208,5690.218095071322
3
+ 1,-475.04172715926325,5552.575607149263
4
+ 1,-3.0084997762223793,5560.943568626222
5
+ 1,-55.835992656834605,5425.282497616835
6
+ 1,-556.3423571615149,5516.629386071515
7
+ 1,-798.7293276068531,5445.739089056853
8
+ 1,-831.8661367345012,5200.425346684501
9
+ 1,-747.198588652529,5374.30297088253
10
+ 1,-420.26596056385824,5332.913056923858
11
+ 1,-271.1869770058056,5319.342549515806
12
+ 1,36.61704801202086,5391.429887731979
13
+ 1,301.40268262302834,5389.612139710971
14
+ 1,-149.43278291676052,5242.934237956761
15
+ 1,-178.18371062845563,5131.547398718455
16
+ 1,-344.31242848795137,5289.838616957952
17
+ 1,-230.8534688342088,5451.796660734209
18
+ 1,123.81965248641245,5218.377356663587
19
+ 1,-346.37018641133545,5376.028569331336
20
+ 1,-271.2351337049322,5328.863885024933
21
+ 1,-354.554715570026,5403.077810960025
22
+ 1,-19.421853013877808,5485.364920013878
23
+ 1,280.9211846086464,5590.702815091353
24
+ 1,219.92735776987683,5516.867885530122
25
+ 1,781.0334815120614,5679.80980158794
26
+ 1,1294.2147923458097,5794.625140154191
27
+ 1,738.501471567386,5867.577001832614
28
+ 1,796.9528952899409,5766.399026290058
29
+ 1,415.4269982696269,5870.755899660373
30
+ 1,786.9046031624202,5653.93211614758
31
+ 1,699.8259613792043,5780.494561230796
32
+ 1,539.745101025057,5709.584150782943
33
+ 1,377.1008301603306,5701.305955438669
34
+ 1,-171.62603119793766,5654.003287164937
35
+ 1,2.582553312521668,5483.3585810364775
36
+ 1,-34.22562033747454,5514.875846412474
37
+ 1,-232.94753657288948,5380.036090195889
38
+ 1,-468.2093499173461,5549.191483465347
39
+ 1,-322.5520717213194,5460.39469793332
40
+ 1,-286.06881459022316,4870.059378248223
41
+ 1,-567.8495337345976,5126.330691409597
42
+ 1,-178.17958404447836,4755.834189569478
43
+ 1,-138.0179383988434,4914.458840338843
44
+ 1,-224.74888886520603,5285.073225435205
45
+ 1,792.8627605627144,5620.162487447286
46
+ 1,1355.6289643675454,6164.484521602455
47
+ 1,986.2797608661922,6162.196124983807
48
+ 1,1059.455769237742,6192.769529952258
49
+ 1,383.32346060172495,6147.518456028276
50
+ 1,-187.89672830752534,5715.406060937526
51
+ 1,-212.61946644455384,5361.829613484554
52
+ 1,72.72524427662756,5103.391602309372
53
+ 1,-95.74246649852375,5238.581337104524
54
+ 1,-120.67574389038145,5559.6276727923805
55
+ 1,-129.05511796418887,5484.728899857189
56
+ 1,-225.81656994822242,5494.042520330223
57
+ 1,-218.372927237976,5302.365695685977
58
+ 1,-527.1306773658152,5229.707354409815
59
+ 1,-787.2566332929837,5426.519151763984
60
+ 1,-1039.0776762177757,5539.477859049775
61
+ 1,-753.3501980635592,5429.758980752559
62
+ 1,-357.5844211273052,5439.306041177304
63
+ 1,-324.8985270979456,5678.245679517945
64
+ 1,-133.5001332835127,5695.581704533513
65
+ 1,-45.999364494503425,5662.909688574503
66
+ 1,-198.8982053530035,5516.533581953002
67
+ 1,-140.84226664971084,5403.844047839711
68
+ 1,-328.0694341550152,5409.443929865015
69
+ 1,-471.04691505620394,5319.741307806204
70
+ 1,-340.9581299499314,4979.624243809932
71
+ 1,-451.5102744182759,4939.252369518276
72
+ 1,-470.3738494522704,5272.67316311227
73
+ 1,-241.2091197384807,5185.855093778481
74
+ 1,208.857413296284,5444.7313112837155
75
+ 1,515.8201019324006,5531.571609717599
76
+ 1,645.0637292085721,5567.486440531427
77
+ 1,600.0432433501519,5726.386967019847
78
+ 1,991.718208446463,5546.432488283537
79
+ 1,1013.1534153918865,5402.554699058114
80
+ 1,917.9498416432871,5331.587882096714
81
+ 1,1015.0218196550877,5173.547445494913
82
+ 1,696.1648921444839,5336.375056005516
83
+ 1,847.2335698491943,5141.959263320807
84
+ 1,306.9893113897788,5080.857405947221
85
+ 1,584.0043413540352,4984.766656686965
86
+ 1,320.81565350241544,4936.522939377584
87
+ 1,90.34779668819283,5252.465610906806
88
+ 1,403.10225090216045,5224.36913916284
89
+ 1,83.73958567298087,5191.8993596540195
90
+ 1,-278.22837426408205,5013.4219235420815
91
+ 1,-594.5906903171735,5002.829538211174
92
+ 1,-638.5744723089219,4758.680377859922
93
+ 1,-820.1630688997875,5052.951763736787
94
+ 1,-777.5222929965912,5052.983144825591
95
+ 1,-937.3473140298456,5133.260108853846
96
+ 1,-766.0759176046413,5175.75865344264
97
+ 1,-601.9624005578062,5336.127374237805
98
+ 1,-43.38206579649068,5912.821508406491
99
+ 1,783.555777528677,5872.092495641322
100
+ 1,1048.3380060975587,5779.248749202441
101
+ 1,942.7156660498758,5657.687045620124
102
+ 1,459.9194845831371,5422.163026676863
103
+ 1,-457.0944462735897,5375.19352051359
104
+ 1,-547.8520567101295,4949.859554259129
105
+ 1,-1007.0066006714123,5301.205921773412
Test/x_test_contribution.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/x_test_to_save.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/x_train_contribution.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/x_train_to_save.csv ADDED
The diff for this file is too large to render. See raw diff
 
Transformation_functions.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ from Eda_functions import format_numbers,line_plot,summary
6
+ import numpy as np
7
+ import re
8
+
9
+ def sanitize_key(key, prefix=""):
10
+ # Use regular expressions to remove non-alphanumeric characters and spaces
11
+ key = re.sub(r'[^a-zA-Z0-9]', '', key)
12
+ return f"{prefix}{key}"
13
+
14
+
15
+ def check_box(options, ad_stock_value,lag_value,num_columns=4, prefix=""):
16
+ num_rows = -(-len(options) // num_columns) # Ceiling division to calculate rows
17
+
18
+ selected_options = []
19
+ adstock_info = {} # Store adstock and lag info for each selected option
20
+ if ad_stock_value!=0:
21
+ for row in range(num_rows):
22
+ cols = st.columns(num_columns)
23
+ for col in cols:
24
+ if options:
25
+ option = options.pop(0)
26
+ key = sanitize_key(f"{option}_{row}", prefix=prefix)
27
+ selected = col.checkbox(option, key=key)
28
+ if selected:
29
+ selected_options.append(option)
30
+
31
+ # Input minimum and maximum adstock values
32
+ adstock = col.slider('Select Adstock Range', 0.0, 1.0, ad_stock_value, step=0.05, format="%.2f",key= f"adstock_{key}" )
33
+
34
+ # Input minimum and maximum lag values
35
+ lag = col.slider('Select Lag Range', 0, 7, lag_value, step=1,key=f"lag_{key}" )
36
+
37
+ # Create a dictionary to store adstock and lag info for the option
38
+ option_info = {
39
+ 'adstock': adstock,
40
+ 'lag': lag}
41
+ # Append the dictionary to the adstock_info list
42
+ adstock_info[option]=option_info
43
+
44
+ else:adstock_info[option]={
45
+ 'adstock': ad_stock_value,
46
+ 'lag': lag_value}
47
+
48
+ return selected_options, adstock_info
49
+ else:
50
+ for row in range(num_rows):
51
+ cols = st.columns(num_columns)
52
+ for col in cols:
53
+ if options:
54
+ option = options.pop(0)
55
+ key = sanitize_key(f"{option}_{row}", prefix=prefix)
56
+ selected = col.checkbox(option, key=key)
57
+ if selected:
58
+ selected_options.append(option)
59
+
60
+ # Input minimum and maximum lag values
61
+ lag = col.slider('Select Lag Range', 0, 7, lag_value, step=1,key=f"lag_{key}" )
62
+
63
+ # dictionary to store adstock and lag info for the option
64
+ option_info = {
65
+ 'lag': lag}
66
+ # Append the dictionary to the adstock_info list
67
+ adstock_info[option]=option_info
68
+
69
+ else:adstock_info[option]={
70
+ 'lag': lag_value}
71
+
72
+ return selected_options, adstock_info
73
+
74
+ def apply_lag(X, features,lag_dict):
75
+ #lag_data=pd.DataFrame()
76
+ for col in features:
77
+ for lag in range(lag_dict[col]['lag'][0], lag_dict[col]['lag'][1] + 1):
78
+ if lag>0:
79
+ X[f'{col}_lag{lag}'] = X[col].shift(periods=lag, fill_value=0)
80
+ return X
81
+
82
+ def apply_adstock(X, variable_name, decay):
83
+ values = X[variable_name].values
84
+ adstock = np.zeros(len(values))
85
+
86
+ for row in range(len(values)):
87
+ if row == 0:
88
+ adstock[row] = values[row]
89
+ else:
90
+ adstock[row] = values[row] + adstock[row - 1] * decay
91
+
92
+ return adstock
93
+
94
+ def top_correlated_features(df,target,media_data):
95
+ corr_df=df.drop(target,axis=1)
96
+ #corr_df[target]=df[target]
97
+ #st.dataframe(corr_df)
98
+ for i in media_data:
99
+ #st.write(media_data[2])
100
+ #st.dataframe(corr_df.filter(like=media_data[2]))
101
+ d=(pd.concat([corr_df.filter(like=i),df[target]],axis=1)).corr()[target]
102
+ d=d.sort_values(ascending=False)
103
+ d=d.drop(target,axis=0)
104
+ corr=pd.DataFrame({'Feature_name':d.index,"Correlation":d.values})
105
+ corr.columns = pd.MultiIndex.from_product([[i], ['Feature_name', 'Correlation']])
106
+
107
+ return corr
108
+
109
+ def top_correlated_features(df,variables,target):
110
+ correlation_df=pd.DataFrame()
111
+ for col in variables:
112
+ d=pd.concat([df.filter(like=col),df[target]],axis=1).corr()[target]
113
+ #st.dataframe(d)
114
+ d=d.sort_values(ascending=False).iloc[1:]
115
+ corr_df=pd.DataFrame({'Media_channel':d.index,'Correlation':d.values})
116
+ corr_df.columns=pd.MultiIndex.from_tuples([(col, 'Variable'), (col, 'Correlation')])
117
+ correlation_df=pd.concat([corr_df,correlation_df],axis=1)
118
+ return correlation_df
119
+
120
+ def top_correlated_feature(df,variable,target):
121
+ d=pd.concat([df.filter(like=variable),df[target]],axis=1).corr()[target]
122
+ # st.dataframe(d)
123
+ d=d.sort_values(ascending=False).iloc[1:]
124
+ # st.dataframe(d)
125
+ corr_df=pd.DataFrame({'Media_channel':d.index,'Correlation':d.values})
126
+ corr_df['Adstock']=corr_df['Media_channel'].map(lambda x:x.split('_adst')[1] if len(x.split('_adst'))>1 else '-')
127
+ corr_df['Lag']=corr_df['Media_channel'].map(lambda x:x.split('_lag')[1][0] if len(x.split('_lag'))>1 else '-' )
128
+ corr_df.drop(['Correlation'],axis=1,inplace=True)
129
+ corr_df['Correlation']=np.round(d.values,2)
130
+ sorted_corr_df= corr_df.loc[corr_df['Correlation'].abs().sort_values(ascending=False).index]
131
+ #corr_df.columns=pd.MultiIndex.from_tuples([(variable, 'Variable'), (variable, 'Correlation')])
132
+ #correlation_df=pd.concat([corr_df,correlation_df],axis=1)
133
+ return sorted_corr_df
all_solutions_2024-05-09.json ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "solution_0": {
3
+ "solution": {
4
+ "media_params": {
5
+ "Broadcast TV": {
6
+ "spend_col": "tv_broadcast_spend",
7
+ "metric_col": "tv_broadcast_grp",
8
+ "half_life": 1.5125527782612616,
9
+ "penetration": 0.7306710045225968,
10
+ "scale": 6661261.92832161,
11
+ "shape": 2.8161330383341983,
12
+ "coeff": 0.04000000000000001
13
+ },
14
+ "Cable TV": {
15
+ "spend_col": "tv_cable_spend",
16
+ "metric_col": "tv_cable_grp",
17
+ "half_life": 1.0115283431416273,
18
+ "penetration": 0.8645370354816814,
19
+ "scale": 6904015.732432723,
20
+ "shape": 0.38530421046089125,
21
+ "coeff": 0.04000000069639975
22
+ },
23
+ "Connected & OTT TV": {
24
+ "spend_col": "stream_video_spend",
25
+ "metric_col": "stream_video_imp",
26
+ "half_life": 0.5387407126474395,
27
+ "penetration": 0.37479811952034575,
28
+ "scale": 52395243.68927538,
29
+ "shape": 0.9891886048110367,
30
+ "coeff": 0.06999999999999999
31
+ },
32
+ "Video": {
33
+ "spend_col": "olv_spend",
34
+ "metric_col": "olv_imp",
35
+ "half_life": 0.9628402347042399,
36
+ "penetration": 0.1339338890582195,
37
+ "scale": 2404356.5978383864,
38
+ "shape": 1.7605314295228363,
39
+ "coeff": 0.04000000000026293
40
+ },
41
+ "Display Prospecting": {
42
+ "spend_col": "disp_prospect_spend",
43
+ "metric_col": "disp_prospect_imp",
44
+ "half_life": 0.3185770016152706,
45
+ "penetration": 0.1470527101992185,
46
+ "scale": 65218855.319753565,
47
+ "shape": 2.2826537278140124,
48
+ "coeff": 0.9999999999999999
49
+ },
50
+ "Display Retargeting": {
51
+ "spend_col": "disp_retarget_spend",
52
+ "metric_col": "disp_retarget_imp",
53
+ "half_life": 0.19649840139877658,
54
+ "penetration": 0.2136738043476821,
55
+ "scale": 52456194.86356406,
56
+ "shape": 1.1049988693888833,
57
+ "coeff": 0.9999999999999999
58
+ },
59
+ "Social Prospecting": {
60
+ "spend_col": "social_prospect_spend",
61
+ "metric_col": "social_prospect_imp",
62
+ "half_life": 0.23348992868088775,
63
+ "penetration": 0.23170623958443773,
64
+ "scale": 18416.13907661135,
65
+ "shape": 2.7416996439407058,
66
+ "coeff": 0.04000000000027258
67
+ },
68
+ "Social Retargeting": {
69
+ "spend_col": "social_retarget_spend",
70
+ "metric_col": "social_retarget_imp",
71
+ "half_life": 0.311145083025538,
72
+ "penetration": 0.07864050141293169,
73
+ "scale": 5734521.583224347,
74
+ "shape": 2.12760192364264,
75
+ "coeff": 0.09999999999999999
76
+ },
77
+ "Search Brand": {
78
+ "spend_col": "search_brand_spend",
79
+ "metric_col": "search_brand_imp",
80
+ "half_life": 0.6410768184353358,
81
+ "penetration": 0.9478746429718543,
82
+ "scale": 64091.710880368904,
83
+ "shape": 1.8822844845279567,
84
+ "coeff": 0.008000000000010674
85
+ },
86
+ "Search Non-brand": {
87
+ "spend_col": "search_nonbrand_spend",
88
+ "metric_col": "search_nonbrand_imp",
89
+ "half_life": 0.021077826067475037,
90
+ "penetration": 0.9970358969389862,
91
+ "scale": 20075934.15955288,
92
+ "shape": 1.0095598649180348,
93
+ "coeff": 0.17500000000000002
94
+ },
95
+ "Digital Partners": {
96
+ "spend_col": "cm_spend",
97
+ "metric_col": "cm_spend",
98
+ "half_life": 0.035288031130940034,
99
+ "penetration": 0.7900892706847193,
100
+ "scale": 16774246.211700687,
101
+ "shape": 0.7709184982171291,
102
+ "coeff": 0.5199999999999999
103
+ },
104
+ "Audio": {
105
+ "spend_col": "audio_spend",
106
+ "metric_col": "audio_imp",
107
+ "half_life": 0.2825119018286497,
108
+ "penetration": 0.5297375597273687,
109
+ "scale": 2068888.3017906512,
110
+ "shape": 1.801467700171006,
111
+ "coeff": 0.018000000000031005
112
+ },
113
+ "Email": {
114
+ "spend_col": "email_spend",
115
+ "metric_col": "email_imp",
116
+ "half_life": 0.27709327146939394,
117
+ "penetration": 0.3730988846104394,
118
+ "scale": 4565323.224523856,
119
+ "shape": 0.4019891584296605,
120
+ "coeff": 0.015000000000000001
121
+ }
122
+ },
123
+ "control_params": {
124
+ "Unemployment": {
125
+ "metric_col": "unemp",
126
+ "coeff": 1.7500000000000413
127
+ },
128
+ "Competitors spending": {
129
+ "metric_col": "comp_spend_log",
130
+ "coeff": -0.2650000008161444
131
+ }
132
+ },
133
+ "other_params": {
134
+ "Trend": {
135
+ "coeff": 1.0639086682507188
136
+ },
137
+ "Seasonality": {
138
+ "coeff": 0.9338025000581551
139
+ },
140
+ "Intercept": {
141
+ "coeff": -0.9999999999990916
142
+ }
143
+ }
144
+ },
145
+ "Base-Media": "Base : Media = 51% : 49%.",
146
+ "Best_Soln": false
147
+ }
148
+ }
classes.py ADDED
@@ -0,0 +1,698 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy.optimize import minimize, LinearConstraint, NonlinearConstraint
3
+ from collections import OrderedDict
4
+ import pandas as pd
5
+ from numerize.numerize import numerize
6
+ # from gekko import GEKKO
7
+ def class_to_dict(class_instance):
8
+ attr_dict = {}
9
+ if isinstance(class_instance, Channel):
10
+ attr_dict["type"] = "Channel"
11
+ attr_dict["name"] = class_instance.name
12
+ attr_dict["dates"] = class_instance.dates
13
+ attr_dict["spends"] = class_instance.actual_spends
14
+ attr_dict["conversion_rate"] = class_instance.conversion_rate
15
+ attr_dict["modified_spends"] = class_instance.modified_spends
16
+ attr_dict["modified_sales"] = class_instance.modified_sales
17
+ attr_dict["response_curve_type"] = class_instance.response_curve_type
18
+ attr_dict["response_curve_params"] = class_instance.response_curve_params
19
+ attr_dict["penalty"] = class_instance.penalty
20
+ attr_dict["bounds"] = class_instance.bounds
21
+ attr_dict["actual_total_spends"] = class_instance.actual_total_spends
22
+ attr_dict["actual_total_sales"] = class_instance.actual_total_sales
23
+ attr_dict["modified_total_spends"] = class_instance.modified_total_spends
24
+ attr_dict["modified_total_sales"] = class_instance.modified_total_sales
25
+ # attr_dict["actual_mroi"] = class_instance.get_marginal_roi("actual")
26
+ # attr_dict["modified_mroi"] = class_instance.get_marginal_roi("modified")
27
+
28
+ elif isinstance(class_instance, Scenario):
29
+ attr_dict["type"] = "Scenario"
30
+ attr_dict["name"] = class_instance.name
31
+ channels = []
32
+ for channel in class_instance.channels.values():
33
+ channels.append(class_to_dict(channel))
34
+ attr_dict["channels"] = channels
35
+ attr_dict["constant"] = class_instance.constant
36
+ attr_dict["correction"] = class_instance.correction
37
+ attr_dict["actual_total_spends"] = class_instance.actual_total_spends
38
+ attr_dict["actual_total_sales"] = class_instance.actual_total_sales
39
+ attr_dict["modified_total_spends"] = class_instance.modified_total_spends
40
+ attr_dict["modified_total_sales"] = class_instance.modified_total_sales
41
+
42
+ return attr_dict
43
+
44
+
45
+ def class_from_dict(attr_dict):
46
+ if attr_dict["type"] == "Channel":
47
+ return Channel.from_dict(attr_dict)
48
+ elif attr_dict["type"] == "Scenario":
49
+ return Scenario.from_dict(attr_dict)
50
+
51
+
52
+ class Channel:
53
+ def __init__(
54
+ self,
55
+ name,
56
+ dates,
57
+ spends,
58
+ sales,
59
+ response_curve_type,
60
+ response_curve_params,
61
+ bounds,channel_bounds_min,channel_bounds_max,
62
+ conversion_rate=1,
63
+ modified_spends=None,
64
+ modified_sales=None,
65
+ penalty=True,
66
+ ):
67
+ self.name = name
68
+ self.dates = dates
69
+ self.conversion_rate = conversion_rate
70
+ self.actual_spends = spends.copy()
71
+ self.actual_sales = sales.copy()
72
+
73
+ if modified_spends is None:
74
+ self.modified_spends = self.actual_spends.copy()
75
+ else:
76
+ self.modified_spends = modified_spends
77
+
78
+ if modified_sales is None:
79
+ # self.modified_sales = self.calculate_sales()
80
+ self.modified_sales = self.actual_sales.copy()
81
+ else:
82
+ self.modified_sales = self.calculate_sales()
83
+ # self.modified_spends = modified_spends
84
+
85
+ self.response_curve_type = response_curve_type
86
+ self.response_curve_params = response_curve_params
87
+ self.bounds = bounds
88
+ self.channel_bounds_min = channel_bounds_min
89
+ self.channel_bounds_max = channel_bounds_max
90
+ self.penalty = penalty
91
+
92
+ self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
93
+ self.power = np.ceil(np.log(self.actual_spends.max()) / np.log(10)) - 3
94
+ # self.actual_sales = None
95
+ # self.actual_sales = self.response_curve(self.actual_spends)#sales.copy()#
96
+ self.actual_total_spends = self.actual_spends.sum()
97
+ self.actual_total_sales = self.actual_sales.sum()
98
+
99
+ self.modified_total_spends = self.modified_spends.sum()
100
+ self.modified_total_sales = self.modified_sales.sum()
101
+ self.delta_spends = self.modified_total_spends - self.actual_total_spends
102
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
103
+ # # # # print(self.actual_total_spends)
104
+ def update_penalty(self, penalty):
105
+ self.penalty = penalty
106
+
107
+ def _modify_spends(self, spends_array, total_spends):
108
+ return spends_array * total_spends / spends_array.sum()
109
+
110
+ def modify_spends(self, total_spends):
111
+ # # # # print(total_spends)
112
+ self.modified_spends[0] = total_spends
113
+ # (
114
+ # self.modified_spends * total_spends / self.modified_spends.sum()
115
+ # )
116
+ # # # # print("in spends")
117
+ # # # # print(self.modified_spends,self.modified_spends.sum())
118
+
119
+ def calculate_sales(self):
120
+ # # # # print("in calc_sales")
121
+ # # # # print(self.modified_spends)
122
+ return self.response_curve(self.modified_spends)
123
+
124
+ def hill_equation(x, Kd, n):
125
+ return x**n / (Kd**n + x**n)
126
+ def response_curve(self, x):
127
+ # # # # print(x)
128
+ # if self.penalty:
129
+ # # # # print("in penalty")
130
+ # x = np.where(
131
+ # x < self.upper_limit,
132
+ # x,
133
+ # self.upper_limit + (x - self.upper_limit) * self.upper_limit / x,
134
+ # )
135
+ if self.response_curve_type == "hill-eq":
136
+ # dividing_parameter = check_dividing_parameter()
137
+ # # # # print("lalala")
138
+ # # # # # print(self.name)\
139
+ # # # # print(len(x))
140
+ # # # # print("in response curve function")
141
+ # # # # print(x)
142
+ if len(x) == 1:
143
+ dividing_rate = self.response_curve_params["num_pos_obsv"]
144
+ # # # # print(dividing_rate)
145
+ # x = np.sum(x)
146
+ else:
147
+ dividing_rate = 1
148
+ # dividing_rate = self.response_curve_params["num_pos_obsv"]
149
+ # x = np.sum(x)
150
+ # dividing_rate = 104
151
+ dividing_rate = self.response_curve_params["num_pos_obsv"]
152
+ Kd= self.response_curve_params["Kd"]
153
+ n= self.response_curve_params["n"]
154
+ x_min= self.response_curve_params["x_min"]
155
+ x_max= self.response_curve_params["x_max"]
156
+ y_min= self.response_curve_params["y_min"]
157
+ y_max= self.response_curve_params['y_max']
158
+ # # # # # print(x_min)
159
+ # # # # # print(Kd,n,x_min,x_max,y_min,y_max)
160
+ # # # # # print(np.sum(x)/104)
161
+ x_inp = ( x/dividing_rate- x_min) / (x_max - x_min)
162
+ # # # # # print("x",x)
163
+ # # # # # print("x_inp",x_inp)
164
+ x_out = x_inp**n / (Kd**n + x_inp**n) #self.hill_equation(x_inp,Kd, n)
165
+ # # # # # print("x_out",x_out)
166
+
167
+
168
+ x_val_inv = (x_out*x_max + (1 - x_out) * x_min)
169
+ sales = (x_val_inv*y_min/y_max)*dividing_rate
170
+ # sales = ((x_max - x_min)*x_out + x_min)*dividing_rate
171
+
172
+ sales[np.isnan(sales)] = 0
173
+ # # # # # print(sales)
174
+ # # # # # print(np.sum(sales))
175
+ # # # # # print("sales",sales)
176
+ # # # # print("aa")
177
+ # # # # print(sales)
178
+ # # # # print("aa1")
179
+ if self.response_curve_type == "s-curve":
180
+ if self.power >= 0:
181
+ x = x / 10**self.power
182
+ x = x.astype("float64")
183
+ K = self.response_curve_params["Kd"]
184
+ b = self.response_curve_params["b"]
185
+ a = self.response_curve_params["a"]
186
+ x0 = self.response_curve_params["x0"]
187
+ sales = K / (1 + b * np.exp(-a * (x - x0)))
188
+ if self.response_curve_type == "linear":
189
+ beta = self.response_curve_params["beta"]
190
+ sales = beta * x
191
+
192
+ return sales
193
+
194
+ def get_marginal_roi(self, flag):
195
+ K = self.response_curve_params["K"]
196
+ a = self.response_curve_params["a"]
197
+ # x = self.modified_total_spends
198
+ # if self.power >= 0 :
199
+ # x = x / 10**self.power
200
+ # x = x.astype('float64')
201
+ # return K*b*a*np.exp(-a*(x-x0)) / (1 + b * np.exp(-a*(x - x0)))**2
202
+ if flag == "actual":
203
+ y = self.response_curve(self.actual_spends)
204
+ # spends_array = self.actual_spends
205
+ # total_spends = self.actual_total_spends
206
+ # total_sales = self.actual_total_sales
207
+
208
+ else:
209
+ y = self.response_curve(self.modified_spends)
210
+ # spends_array = self.modified_spends
211
+ # total_spends = self.modified_total_spends
212
+ # total_sales = self.modified_total_sales
213
+
214
+ # spends_inc_1 = self._modify_spends(spends_array, total_spends+1)
215
+ mroi = a * (y) * (1 - y / K)
216
+ return mroi.sum() / len(self.modified_spends)
217
+ # spends_inc_1 = self.spends_array + 1
218
+ # new_total_sales = self.response_curve(spends_inc_1).sum()
219
+ # return (new_total_sales - total_sales) / len(self.modified_spends)
220
+
221
+ def update(self, total_spends):
222
+ self.modify_spends(total_spends)
223
+ self.modified_sales = self.calculate_sales()
224
+ self.modified_total_spends = self.modified_spends.sum()
225
+ self.modified_total_sales = self.modified_sales.sum()
226
+ self.delta_spends = self.modified_total_spends - self.actual_total_spends
227
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
228
+
229
+ def update_bounds_min(self, modified_bound):
230
+ self.channel_bounds_min = modified_bound
231
+
232
+ def update_bounds_max(self, modified_bound):
233
+ self.channel_bounds_max = modified_bound
234
+
235
+ def intialize(self):
236
+ self.new_spends = self.old_spends
237
+
238
+ def __str__(self):
239
+ return f"{self.name},{self.actual_total_sales}, {self.modified_total_spends}"
240
+
241
+ @classmethod
242
+ def from_dict(cls, attr_dict):
243
+ return Channel(
244
+ name=attr_dict["name"],
245
+ dates=attr_dict["dates"],
246
+ spends=attr_dict["spends"],
247
+ bounds=attr_dict["bounds"],
248
+ modified_spends=attr_dict["modified_spends"],
249
+ response_curve_type=attr_dict["response_curve_type"],
250
+ response_curve_params=attr_dict["response_curve_params"],
251
+ penalty=attr_dict["penalty"],
252
+ )
253
+
254
+ def update_response_curves(self, response_curve_params):
255
+ self.response_curve_params = response_curve_params
256
+
257
+
258
+ class Scenario:
259
+ def __init__(self, name, channels, constant, correction):
260
+ self.name = name
261
+ self.channels = channels
262
+ self.constant = constant
263
+ self.correction = correction
264
+
265
+ self.actual_total_spends = self.calculate_modified_total_spends()
266
+ self.actual_total_sales = self.calculate_actual_total_sales()
267
+ self.modified_total_sales = self.calculate_modified_total_sales()
268
+ self.modified_total_spends = self.calculate_modified_total_spends()
269
+ self.delta_spends = self.modified_total_spends - self.actual_total_spends
270
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
271
+
272
+ def update_penalty(self, value):
273
+ for channel in self.channels.values():
274
+ channel.update_penalty(value)
275
+
276
+ def calculate_modified_total_spends(self):
277
+ total_actual_spends = 0.0
278
+ for channel in self.channels.values():
279
+ total_actual_spends += channel.actual_total_spends * 1.0
280
+ return total_actual_spends
281
+
282
+ def calculate_modified_total_spends(self):
283
+ total_modified_spends = 0.0
284
+ for channel in self.channels.values():
285
+ # import streamlit as st
286
+ # st.write(channel.modified_total_spends )
287
+ total_modified_spends += (
288
+ channel.modified_total_spends * 1.0
289
+
290
+ )
291
+ return total_modified_spends
292
+
293
+ def calculate_actual_total_sales(self):
294
+ total_actual_sales = 0#self.constant.sum() + self.correction.sum()
295
+ # # # # print("a")
296
+ for channel in self.channels.values():
297
+ total_actual_sales += channel.actual_total_sales
298
+ # # # # # print(channel.actual_total_sales)
299
+ # # # # # print(total_actual_sales)
300
+ return total_actual_sales
301
+
302
+ def calculate_modified_total_sales(self):
303
+
304
+ total_modified_sales = 0 #self.constant.sum() + self.correction.sum()
305
+ # # # # print(total_modified_sales)
306
+ for channel in self.channels.values():
307
+ # # # # print(channel,channel.modified_total_sales)
308
+ total_modified_sales += channel.modified_total_sales
309
+ return total_modified_sales
310
+
311
+ def update(self, channel_name, modified_spends):
312
+ # # # # print("in updtw")
313
+ self.channels[channel_name].update(modified_spends)
314
+ self.modified_total_sales = self.calculate_modified_total_sales()
315
+ self.modified_total_spends = self.calculate_modified_total_spends()
316
+ self.delta_spends = self.modified_total_spends - self.actual_total_spends
317
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
318
+
319
+ def update_bounds_min(self, channel_name,modified_bound):
320
+ # self.modify_spends(total_spends)
321
+ self.channels[channel_name].update_bounds_min(modified_bound)
322
+
323
+ def update_bounds_max(self, channel_name,modified_bound):
324
+ # self.modify_spends(total_spends)
325
+ self.channels[channel_name].update_bounds_max(modified_bound)
326
+
327
+ # def optimize_spends(self, sales_percent, channels_list, algo="COBYLA"):
328
+ # desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
329
+
330
+ # def constraint(x):
331
+ # for ch, spends in zip(channels_list, x):
332
+ # self.update(ch, spends)
333
+ # return self.modified_total_sales - desired_sales
334
+
335
+ # bounds = []
336
+ # for ch in channels_list:
337
+ # bounds.append(
338
+ # (1 + np.array([-50.0, 100.0]) / 100.0)
339
+ # * self.channels[ch].actual_total_spends
340
+ # )
341
+
342
+ # initial_point = []
343
+ # for bound in bounds:
344
+ # initial_point.append(bound[0])
345
+
346
+ # power = np.ceil(np.log(sum(initial_point)) / np.log(10))
347
+
348
+ # constraints = [NonlinearConstraint(constraint, -1.0, 1.0)]
349
+
350
+ # res = minimize(
351
+ # lambda x: sum(x) / 10 ** (power),
352
+ # bounds=bounds,
353
+ # x0=initial_point,
354
+ # constraints=constraints,
355
+ # method=algo,
356
+ # options={"maxiter": int(2e7), "catol": 1},
357
+ # )
358
+
359
+ # for channel_name, modified_spends in zip(channels_list, res.x):
360
+ # self.update(channel_name, modified_spends)
361
+
362
+ # return zip(channels_list, res.x)
363
+
364
+
365
+
366
+
367
+
368
+
369
+ def optimize_spends(self, sales_percent, channels_list, algo="trust-constr"):
370
+ num_channels = len(channels_list)
371
+ # # # # # print("%"*100)
372
+ desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
373
+
374
+ def constraint(x):
375
+ for ch, spends in zip(channels_list, x):
376
+ self.update(ch, spends)
377
+ return self.modified_total_sales - desired_sales
378
+
379
+ # def calc_overall_bounds(channels_list):
380
+ # total_spends=0
381
+ # for ch in zip(channels_list):
382
+ # # print(ch)
383
+ # total_spends= total_spends+self.channels[ch].actual_total_spends
384
+ # return total_spends
385
+
386
+
387
+ bounds = []
388
+ for ch in channels_list:
389
+ # bounds.append(
390
+ # (1+np.array([-50.0, 100.0]) / 100.0)
391
+ # * self.channels[ch].actual_total_spends
392
+ # )
393
+ lb = (1- int(self.channels[ch].channel_bounds_min) / 100) * self.channels[ch].actual_total_spends
394
+ ub = (1+ int(self.channels[ch].channel_bounds_max) / 100) * self.channels[ch].actual_total_spends
395
+ bounds.append((lb,ub))
396
+ # # # # # print(self.channels[ch].actual_total_spends)
397
+ initial_point = []
398
+ for bound in bounds:
399
+ initial_point.append(bound[0])
400
+ # initial_point = np.nan_to_num(initial_point, nan=0.0, posinf=0.0, neginf=0.0)
401
+
402
+ power = np.ceil(np.log(sum(initial_point)) / np.log(10))
403
+
404
+ constraints = [NonlinearConstraint(constraint, -1.0, 1.0),
405
+ # LinearConstraint(np.ones((num_channels,)), lb = -50*calc_overall_bounds(channels_list), ub = 50*calc_overall_bounds(channels_list))
406
+ ]
407
+
408
+ res = minimize(
409
+ lambda x: sum(x) / 10 ** (power),
410
+ bounds=bounds,
411
+ x0=initial_point,
412
+ constraints=constraints,
413
+ method=algo,
414
+ options={"maxiter": int(2e7), "xtol": 10},
415
+ )
416
+
417
+ for channel_name, modified_spends in zip(channels_list, res.x):
418
+ self.update(channel_name, modified_spends)
419
+
420
+ return zip(channels_list, res.x)
421
+
422
+
423
+
424
+ def optimize(self, spends_percent, channels_list):
425
+ # channels_list = self.channels.keys()
426
+ num_channels = len(channels_list)
427
+ spends_constant = []
428
+ spends_constraint = 0.0
429
+ for channel_name in channels_list:
430
+ # spends_constraint += self.channels[channel_name].modified_total_spends
431
+ spends_constant.append(self.channels[channel_name].conversion_rate)
432
+ # # # # print(spends_constant)
433
+ spends_constraint += (
434
+ self.channels[channel_name].actual_total_spends+ self.channels[channel_name].delta_spends #st.session_state["total_spends_change_abs_slider_options"]
435
+ )
436
+ # # # # print("delta spends",self.channels[channel_name].delta_spends)
437
+ # spends_constraint = spends_constraint * (1 + spends_percent / 100)
438
+ constraint= LinearConstraint(np.ones((num_channels,)), lb = spends_constraint, ub = spends_constraint)
439
+ # constraint = LinearConstraint(
440
+ # np.array(spends_constant),
441
+ # lb=spends_constraint,
442
+ # ub=spends_constraint,
443
+ # )
444
+ bounds = []
445
+ old_spends = []
446
+ for channel_name in channels_list:
447
+ _channel_class = self.channels[channel_name]
448
+ channel_bounds = _channel_class.bounds
449
+ channel_actual_total_spends = _channel_class.actual_total_spends + _channel_class.delta_spends
450
+ # * (
451
+ # (1 + _channel_class.delta_spends / 100)
452
+ # )
453
+ old_spends.append(channel_actual_total_spends)
454
+ # bounds.append((1+ channel_bounds / 100) * channel_actual_total_spends)
455
+ lb = (1- int(_channel_class.channel_bounds_min) / 100) * _channel_class.actual_total_spends
456
+ ub = (1+ int(_channel_class.channel_bounds_max) / 100) * _channel_class.actual_total_spends
457
+ bounds.append((lb,ub))
458
+ # # # # print("aaaaaa")
459
+ # # # print((_channel_class.channel_bounds_max,_channel_class.channel_bounds_min))
460
+ # _channel_class.channel_bounds_min
461
+ # _channel_class.channel_bounds_max
462
+ def cost_func1(channel,x):
463
+ response_curve_params = pd.read_excel("response_curves_parameters.xlsx",index_col = "channel")
464
+ param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
465
+
466
+ Kd= param_dicts["Kd"][channel]
467
+ n= param_dicts["n"][channel]
468
+ x_min= param_dicts["x_min"][channel]
469
+ x_max= param_dicts["x_max"][channel]
470
+ y_min= param_dicts["y_min"][channel]
471
+ y_max= param_dicts['y_max'][channel]
472
+ division_parameter = param_dicts['num_pos_obsv'][channel]
473
+ x_inp = ( x/division_parameter- x_min) / (x_max - x_min)
474
+ # # # # print(x_inp)
475
+ x_out = x_inp**n / (Kd**n + x_inp**n)
476
+ x_val_inv = (x_out*x_max + (1 - x_out) * x_min)
477
+ sales = (x_val_inv*y_min/y_max)*division_parameter
478
+ if np.isnan(sales):
479
+ # # # # print(sales,channel)
480
+ sales = 0
481
+ # # # # print(sales,channel)
482
+ return sales
483
+ def objective_function(x):
484
+ sales = 0
485
+ it = 0
486
+ for channel_name, modified_spends in zip(channels_list, x):
487
+ # sales = sales + cost_func1(channel_name,modified_spends)
488
+ # # print(channel_name, modified_spends,cost_func1(channel_name, modified_spends))
489
+ it+=1
490
+ self.update(channel_name, modified_spends)
491
+ # # # # print(self.modified_total_sales)
492
+ # # # # print(channel_name, modified_spends)
493
+ return -1 * self.modified_total_sales
494
+
495
+ # # # # print(bounds)
496
+ # # # # # print("$"*100)
497
+ res = minimize(
498
+ lambda x: objective_function(x)/1e3,
499
+ method="trust-constr",
500
+ x0=old_spends,
501
+ constraints=constraint,
502
+ bounds=bounds,
503
+ options={"maxiter": int(1e7), "xtol": 0.1},
504
+ )
505
+
506
+ for channel_name, modified_spends in zip(channels_list, res.x):
507
+ # # # # print("aaaaaaaaaaaaaa")
508
+ self.update(channel_name, modified_spends)
509
+ # # # # print(channel_name, modified_spends,cost_func1(channel_name, modified_spends))
510
+
511
+ # # print(it)
512
+
513
+ return zip(channels_list, res.x)
514
+
515
+
516
+ def hill_equation(self,x, Kd, n):
517
+ return x**n / (Kd**n + x**n)
518
+
519
+
520
+
521
+ # def spends_optimisation(self, spends_percent,channels_list):
522
+ # m = GEKKO(remote=False)
523
+ # # Define variables
524
+ # # Initialize 13 variables with specific bounds
525
+ # response_curve_params = pd.read_excel(r"C:\Users\PragyaJatav\Downloads\Untitled Folder 2\simulator uploaded - Copy\Simulator-UOPX\response_curves_parameters.xlsx",index_col = "channel")
526
+ # param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
527
+
528
+ # initial_values = list(param_dicts["x_min"].values())
529
+ # current_spends = list(param_dicts["current_spends"].values())
530
+ # lower_bounds = list(param_dicts["x_min"].values())
531
+
532
+ # num_channels = len(channels_list)
533
+
534
+ # x_vars=[]
535
+ # x_vars = [m.Var(value=param_dicts["current_spends"][_], lb=param_dicts["x_min"][_]*104, ub=5*param_dicts["current_spends"][_]) for _ in channels_list]
536
+ # # # # # print(x_vars)
537
+ # # x_vars,lower_bounds
538
+
539
+ # # Define the objective function to minimize
540
+ # cost = 0
541
+ # spends = 0
542
+ # i = 0
543
+ # for i,c in enumerate(channels_list):
544
+ # # # # # # print(c)
545
+ # # # # # # print(x_vars[i])
546
+ # cost = cost + (self.cost_func(c, x_vars[i]))
547
+ # spends = spends +x_vars[i]
548
+
549
+
550
+ # m.Maximize(cost)
551
+
552
+ # # Define constraints
553
+ # m.Equation(spends == sum(current_spends)*(1 + spends_percent / 100))
554
+ # m.Equation(spends <= sum(current_spends)*0.5)
555
+ # m.Equation(spends >= sum(current_spends)*1.5)
556
+
557
+ # m.solve(disp=True)
558
+
559
+ # for i, var in enumerate(x_vars):
560
+ # # # # # print(f"x{i+1} = {var.value[0]}")
561
+
562
+ # for channel_name, modified_spends in zip(channels_list, x_vars):
563
+ # self.update(channel_name, modified_spends.value[0])
564
+
565
+ # return zip(channels_list, x_vars)
566
+
567
+ def save(self):
568
+ details = {}
569
+ actual_list = []
570
+ modified_list = []
571
+ data = {}
572
+ channel_data = []
573
+
574
+ summary_rows = []
575
+ actual_list.append(
576
+ {
577
+ "name": "Total",
578
+ "Spends": self.actual_total_spends,
579
+ "Sales": self.actual_total_sales,
580
+ }
581
+ )
582
+ modified_list.append(
583
+ {
584
+ "name": "Total",
585
+ "Spends": self.modified_total_spends,
586
+ "Sales": self.modified_total_sales,
587
+ }
588
+ )
589
+ for channel in self.channels.values():
590
+ name_mod = channel.name.replace("_", " ")
591
+ if name_mod.lower().endswith(" imp"):
592
+ name_mod = name_mod.replace("Imp", " Impressions")
593
+ summary_rows.append(
594
+ [
595
+ name_mod,
596
+ channel.actual_total_spends,
597
+ channel.modified_total_spends,
598
+ channel.actual_total_sales,
599
+ channel.modified_total_sales,
600
+ round(channel.actual_total_sales / channel.actual_total_spends, 2),
601
+ round(
602
+ channel.modified_total_sales / channel.modified_total_spends,
603
+ 2,
604
+ ),
605
+ channel.get_marginal_roi("actual"),
606
+ channel.get_marginal_roi("modified"),
607
+ ]
608
+ )
609
+ data[channel.name] = channel.modified_spends
610
+ data["Date"] = channel.dates
611
+ data["Sales"] = (
612
+ data.get("Sales", np.zeros((len(channel.dates),)))
613
+ + channel.modified_sales
614
+ )
615
+ actual_list.append(
616
+ {
617
+ "name": channel.name,
618
+ "Spends": channel.actual_total_spends,
619
+ "Sales": channel.actual_total_sales,
620
+ "ROI": round(
621
+ channel.actual_total_sales / channel.actual_total_spends, 2
622
+ ),
623
+ }
624
+ )
625
+ modified_list.append(
626
+ {
627
+ "name": channel.name,
628
+ "Spends": channel.modified_total_spends,
629
+ "Sales": channel.modified_total_sales,
630
+ "ROI": round(
631
+ channel.modified_total_sales / channel.modified_total_spends,
632
+ 2,
633
+ ),
634
+ "Marginal ROI": channel.get_marginal_roi("modified"),
635
+ }
636
+ )
637
+
638
+ channel_data.append(
639
+ {
640
+ "channel": channel.name,
641
+ "spends_act": channel.actual_total_spends,
642
+ "spends_mod": channel.modified_total_spends,
643
+ "sales_act": channel.actual_total_sales,
644
+ "sales_mod": channel.modified_total_sales,
645
+ }
646
+ )
647
+ summary_rows.append(
648
+ [
649
+ "Total",
650
+ self.actual_total_spends,
651
+ self.modified_total_spends,
652
+ self.actual_total_sales,
653
+ self.modified_total_sales,
654
+ round(self.actual_total_sales / self.actual_total_spends, 2),
655
+ round(self.modified_total_sales / self.modified_total_spends, 2),
656
+ 0.0,
657
+ 0.0,
658
+ ]
659
+ )
660
+ details["Actual"] = actual_list
661
+ details["Modified"] = modified_list
662
+ columns_index = pd.MultiIndex.from_product(
663
+ [[""], ["Channel"]], names=["first", "second"]
664
+ )
665
+ columns_index = columns_index.append(
666
+ pd.MultiIndex.from_product(
667
+ [["Spends", "NRPU", "ROI", "MROI"], ["Actual", "Simulated"]],
668
+ names=["first", "second"],
669
+ )
670
+ )
671
+ details["Summary"] = pd.DataFrame(summary_rows, columns=columns_index)
672
+ data_df = pd.DataFrame(data)
673
+ channel_list = list(self.channels.keys())
674
+ data_df = data_df[["Date", *channel_list, "Sales"]]
675
+
676
+ details["download"] = {
677
+ "data_df": data_df,
678
+ "channels_df": pd.DataFrame(channel_data),
679
+ "total_spends_act": self.actual_total_spends,
680
+ "total_sales_act": self.actual_total_sales,
681
+ "total_spends_mod": self.modified_total_spends,
682
+ "total_sales_mod": self.modified_total_sales,
683
+ }
684
+
685
+ return details
686
+
687
+ @classmethod
688
+ def from_dict(cls, attr_dict):
689
+ channels_list = attr_dict["channels"]
690
+ channels = {
691
+ channel["name"]: class_from_dict(channel) for channel in channels_list
692
+ }
693
+ return Scenario(
694
+ name=attr_dict["name"],
695
+ channels=channels,
696
+ constant=attr_dict["constant"],
697
+ correction=attr_dict["correction"],
698
+ )
config.yaml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ credentials:
2
+ usernames:
3
+ UOPX:
4
5
+ name: Geetakrishna
6
+ password: '$2b$12$zwr3OM11ot9Raw8kHwPtYurvaLIImdWKfpd..svFNaW9pmhKhfaP6'
7
+ cookie:
8
+ expiry_days: 1
9
+ key: some_signature_key
10
+ name: some_cookie_name
11
+ preauthorized:
12
+ emails:
13
data_import.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b626ee3d856ae50a1e6778103d5749f50d9e871a93204414b0e9c2fe36e20994
3
+ size 2246177
data_test_overview_panel_#total_approved_accounts_revenue.xlsx ADDED
Binary file (402 kB). View file
 
enviroment.yml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: myenv
2
+ channels:
3
+ - conda-forge
4
+ - plotly
5
+ dependencies:
6
+ - python=3.8
7
+ - plotly
8
+ - plotly-orca
9
+ - pip
10
+ - pip:
11
+ - -r requirements.txt
final_df_transformed.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:eae2c94951ed0195c1199a59e33ace8bad5921846c2d5e797bced2e1cb565f44
3
+ size 9139766
image (2).png ADDED
input_data_example.xlsx ADDED
Binary file (10.1 kB). View file
 
metrics_level_data/Overview_data_test.xlsx ADDED
Binary file (39.7 kB). View file
 
metrics_level_data/Overview_data_test_panel@#revenue.xlsx ADDED
Binary file (57.6 kB). View file
 
pages/1_Model_Quality.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import plotly.express as px
5
+ import Streamlit_functions as sf
6
+ import response_curves_model_quality_base as rc1
7
+ st.set_page_config(
8
+ layout="wide"
9
+ )
10
+ from pptx import Presentation
11
+ from pptx.util import Inches
12
+ from io import BytesIO
13
+ import plotly.io as pio
14
+ import Streamlit_functions as sf
15
+ import response_curves_model_quality_base as rc1
16
+
17
+
18
+ def save_ppt_file():
19
+
20
+ # Initialize PowerPoint presentation
21
+ prs = Presentation()
22
+ # Helper function to add Plotly figure to slide
23
+ def add_plotly_chart_to_slide(slide, fig, left, top, width, height):
24
+ img_stream = BytesIO()
25
+ pio.write_image(fig, img_stream, format='png')
26
+ slide.shapes.add_picture(img_stream, left, top, width, height)
27
+
28
+ # Slide 1: Model Quality with Chart
29
+ slide_1 = prs.slides.add_slide(prs.slide_layouts[5])
30
+ title_1 = slide_1.shapes.title
31
+ title_1.text = "Model Quality"
32
+ i = 0
33
+ # # print (i)
34
+ # Generate Plotly chart
35
+ fig = sf.mmm_model_quality()
36
+
37
+ # Add the Plotly chart to the slide
38
+ add_plotly_chart_to_slide(slide_1, fig, Inches(1), Inches(2), width=Inches(9), height=Inches(4.5))
39
+ i = i+1
40
+ # # print (i)
41
+ # Slide 2: Media Data Elasticity
42
+ slide_2 = prs.slides.add_slide(prs.slide_layouts[5])
43
+ title_2 = slide_2.shapes.title
44
+ title_2.text = "Media Data Elasticity"
45
+ i = i+1
46
+ # # print (i)
47
+ # Generate Elasticity chart
48
+ media_df = sf.media_data()
49
+ fig = sf.elasticity(media_df)
50
+ fig.update_layout(
51
+ margin=dict(l=150, r=50, t=50, b=50), # Adjust margins
52
+ # xaxis=dict(tickangle=-45) # Rotate x-axis labels if needed
53
+ )
54
+ i = i+1
55
+ # # print (i)
56
+ # Add the Plotly chart to the slide
57
+ add_plotly_chart_to_slide(slide_2, fig, Inches(1), Inches(2), width=Inches(8), height=Inches(4.5))
58
+ i = i+1
59
+ # # print (i)
60
+ # Slide 3: Half-Life Analysis
61
+ slide_3 = prs.slides.add_slide(prs.slide_layouts[5])
62
+ title_3 = slide_3.shapes.title
63
+ title_3.text = "Half-Life Analysis"
64
+ i = i+1
65
+ # # print (i)
66
+ # Generate Half-Life chart
67
+ fig = sf.half_life(media_df)
68
+ fig.update_layout(
69
+ margin=dict(l=150, r=100, t=50, b=50), # Adjust margins
70
+ # xaxis=dict(tickangle=-45) # Rotate x-axis labels if needed
71
+ )
72
+ i = i+1
73
+ # # print (i)
74
+ # Add the Plotly chart to the slide
75
+ add_plotly_chart_to_slide(slide_3, fig, Inches(1), Inches(2), width=Inches(8), height=Inches(4.5))
76
+ i = i+1
77
+ # # print (i)
78
+ # Slide 4: Response Curves
79
+
80
+ # Generate Response Curves chart
81
+ channels = [
82
+ 'Broadcast TV',
83
+ 'Cable TV',
84
+ 'Connected & OTT TV',
85
+ 'Display Prospecting',
86
+ 'Display Retargeting',
87
+ 'Video',
88
+ 'Social Prospecting',
89
+ 'Social Retargeting',
90
+ 'Search Brand',
91
+ 'Search Non-brand',
92
+ 'Digital Partners',
93
+ 'Audio',
94
+ 'Email']
95
+ i = 4
96
+ for channel_name in channels:
97
+ slide_4 = prs.slides.add_slide(prs.slide_layouts[5])
98
+ title_4 = slide_4.shapes.title
99
+ title_4.text = "Response Curves"
100
+ i = i+1
101
+ # # print (i)
102
+ selected_option = channel_name
103
+ selected_option2 = 'View Line Plot'
104
+ fig = rc1.response_curves(selected_option, selected_option2)
105
+ # Add the Plotly chart to the slide
106
+ add_plotly_chart_to_slide(slide_4, fig, Inches(1), Inches(2), width=Inches(6), height=Inches(4.5))
107
+ # Save the PowerPoint presentation
108
+ # prs.save('MMM_Model_Quality_Presentation.pptx')
109
+ # # # print("PowerPoint slides created successfully.")
110
+
111
+ # Save to a BytesIO object
112
+ ppt_stream = BytesIO()
113
+ prs.save(ppt_stream)
114
+ ppt_stream.seek(0)
115
+
116
+ return ppt_stream.getvalue()
117
+
118
+
119
+
120
+
121
+ st.header("Model Quality")
122
+ # st.write("MMM Model Quality")
123
+
124
+ st.plotly_chart(sf.mmm_model_quality(),use_container_width=True)
125
+ fig = sf.mmm_model_quality()
126
+ # # print("aaa")
127
+ # fig.write_image("chart.png")
128
+ # # print("bbb")
129
+
130
+ media_df = sf.media_data()
131
+ # Create two columns for start date and end date input
132
+ col1, col2 , col3 = st.columns([1,0.2,1])
133
+ df1 = sf.model_metrics_table_func()
134
+ st.dataframe(df1,hide_index = True,use_container_width=True)
135
+
136
+ # st.plotly_chart(sf.elasticity_and_media(media_df))
137
+ with col1:
138
+ st.plotly_chart(sf.elasticity(media_df))
139
+ fig = sf.elasticity(media_df)
140
+ # fig.write_image("chart.png",engine="orca")
141
+ with col2:
142
+ st.write("")
143
+ with col3:
144
+ st.plotly_chart(sf.half_life(media_df))
145
+ fig = sf.elasticity(media_df)
146
+ # fig.write_image("chart.png",engine="orca")
147
+
148
+
149
+ # Dropdown menu options
150
+ options = [
151
+ 'Broadcast TV',
152
+ 'Cable TV',
153
+ 'Connected & OTT TV',
154
+ 'Display Prospecting',
155
+ 'Display Retargeting',
156
+ 'Video',
157
+ 'Social Prospecting',
158
+ 'Social Retargeting',
159
+ 'Search Brand',
160
+ 'Search Non-brand',
161
+ 'Digital Partners',
162
+ 'Audio',
163
+ 'Email']
164
+ options1 = [
165
+ 'View Line Plot',
166
+ 'View Scattered Plot',
167
+ "View Both"]
168
+ col1, col2 = st.columns(2)
169
+ # Create a dropdown menu
170
+ with col1:
171
+ selected_option = st.selectbox('Select A Media Channel:', options)
172
+ selected_option2 = st.selectbox('Select A Chart Type', options1)
173
+ # Display the selected option
174
+
175
+ with col2:
176
+ st.write("")
177
+ st.plotly_chart(rc1.response_curves(selected_option,selected_option2))
178
+
179
+ if st.button("Prepare Analysis Download"):
180
+ ppt_file = save_ppt_file()
181
+ # Add a download button
182
+ st.download_button(
183
+ label="Download Analysis",
184
+ data=ppt_file,
185
+ file_name="MMM_Model_Quality_Presentation.pptx",
186
+ mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
187
+ )
188
+
189
+
pages/2_Scenario_Planner.py ADDED
The diff for this file is too large to render. See raw diff
 
pages/3_Saved_Scenarios.py ADDED
@@ -0,0 +1,616 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from numerize.numerize import numerize
3
+ import io
4
+ import pandas as pd
5
+ from utilities import (format_numbers,decimal_formater,
6
+ channel_name_formating,
7
+ load_local_css,set_header,
8
+ initialize_data,
9
+ load_authenticator)
10
+ from openpyxl import Workbook
11
+ from openpyxl.styles import Alignment,Font,PatternFill
12
+ import pickle
13
+ import streamlit_authenticator as stauth
14
+ import yaml
15
+ from yaml import SafeLoader
16
+ from classes import class_from_dict
17
+ import plotly.graph_objects as go
18
+
19
+ from pptx import Presentation
20
+ from pptx.util import Inches
21
+ from io import BytesIO
22
+ import plotly.io as pio
23
+
24
+ st.set_page_config(layout='wide')
25
+ load_local_css('styles.css')
26
+ set_header()
27
+ scenarios_to_compare = []
28
+ st.title("Saved Scenarios")
29
+ # for k, v in st.session_state.items():
30
+ # if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
31
+ # st.session_state[k] = v
32
+
33
+
34
+
35
+ def comparison_scenarios_df():
36
+
37
+ ## create summary page
38
+ if len(scenarios_to_compare) == 0:
39
+ return
40
+ summary_df_spend = None
41
+ summary_df_prospect = None
42
+ # summary_df_efficiency = None
43
+ #=# # # print(scenarios_to_download)
44
+ for scenario_name in scenarios_to_compare:
45
+ scenario_dict = st.session_state['saved_scenarios'][scenario_name]
46
+ _spends = []
47
+ column_names = ['Date']
48
+ _sales = None
49
+ dates = None
50
+ summary_rows_spend = []
51
+ summary_rows_prospects = []
52
+ for channel in scenario_dict['channels']:
53
+ if dates is None:
54
+ dates = channel.get('dates')
55
+ _spends.append(dates)
56
+ if _sales is None:
57
+ _sales = channel.get('modified_sales')
58
+ else:
59
+ _sales += channel.get('modified_sales')
60
+ _spends.append(channel.get('modified_spends') * channel.get('conversion_rate'))
61
+ column_names.append(channel.get('name'))
62
+
63
+ name_mod = channel_name_formating(channel['name'])
64
+ summary_rows_spend.append([name_mod,
65
+ channel.get('modified_total_spends') * channel.get('conversion_rate')])
66
+ summary_rows_prospects.append([name_mod,
67
+ channel.get('modified_total_sales')])
68
+
69
+ _spends.append(_sales)
70
+ # column_names.append('NRPU')
71
+ # scenario_df = pd.DataFrame(_spends).T
72
+ # scenario_df.columns = column_names
73
+
74
+ # summary_rows.append(['Total',
75
+ # scenario_dict.get('modified_total_spends') ,
76
+ # scenario_dict.get('modified_total_sales'),
77
+ # scenario_dict.get('modified_total_sales') / scenario_dict.get('modified_total_spends'),
78
+ # '-',
79
+ # scenario_dict.get('modified_total_spends') / scenario_dict.get('modified_total_sales')])
80
+ # columns_index = pd.MultiIndex.from_product([[''],['Channel']], names=["first", "second"])
81
+ # columns_index = columns_index.append(pd.MultiIndex.from_product([[scenario_name],['Spends','NRPU','ROI','MROI','Spends per NRPU']], names=["first", "second"]))
82
+ columns_index = ['Channel',scenario_name]
83
+ if summary_df_spend is None:
84
+ summary_df_spend = pd.DataFrame(summary_rows_spend, columns = columns_index)
85
+ summary_df_spend = summary_df_spend.set_index('Channel')
86
+ else:
87
+ _df = pd.DataFrame(summary_rows_spend, columns = columns_index)
88
+ _df = _df.set_index('Channel')
89
+ summary_df_spend = summary_df_spend.merge(_df, left_index=True, right_index=True)
90
+
91
+ if summary_df_prospect is None:
92
+ summary_df_prospect = pd.DataFrame(summary_rows_prospects, columns = columns_index)
93
+ summary_df_prospect = summary_df_prospect.set_index('Channel')
94
+ else:
95
+ _df = pd.DataFrame(summary_rows_prospects, columns = columns_index)
96
+ _df = _df.set_index('Channel')
97
+ summary_df_prospect = summary_df_prospect.merge(_df, left_index=True, right_index=True)
98
+ st.session_state['disable_download_button'] = False
99
+
100
+ efficiency_df = pd.DataFrame(index = summary_df_prospect.index)
101
+
102
+ for c in summary_df_spend.columns:
103
+ efficiency_df[c] = (summary_df_prospect[c]/summary_df_prospect[c].sum())/(summary_df_spend[c]/summary_df_spend[c].sum())
104
+ efficiency_df[c] = efficiency_df[c].round(2)
105
+
106
+ return summary_df_spend,summary_df_prospect,efficiency_df
107
+ import matplotlib.colors as mcolors
108
+ import plotly.colors as pc
109
+
110
+ def rgb_to_hex(rgb):
111
+ """Convert RGB tuple to hex color."""
112
+ return mcolors.to_hex(rgb)
113
+
114
+ def generate_color_gradient(start_color, end_color, num_colors):
115
+ """Generate a list of hex color codes transitioning from start_color to end_color."""
116
+ if num_colors == 1:
117
+ return [start_color]
118
+ # Define the color scale from start to end color using hex codes
119
+ colorscale = [[0, start_color], [1, end_color]]
120
+
121
+ # Generate the colors
122
+ colors = pc.sample_colorscale(
123
+ colorscale,
124
+ [i / (num_colors - 1) for i in range(num_colors)],
125
+ colortype='hex' # Use 'rgb' to get colors in RGB format
126
+ )
127
+
128
+ # # print(colors)
129
+ # Convert RGB tuples to hex
130
+ # hex_colors = [rgb_to_hex(color) for color in colors]
131
+ return colors
132
+
133
+ # def generate_color_gradient(start_color, end_color, num_colors):
134
+ # import plotly.express as px
135
+ # """Generate a list of hex color codes transitioning from start_color to end_color."""
136
+ # colors = px.colors.sequential.Plasma # Using a built-in color scale
137
+ # custom_colors = px.colors.sample_colorscale(
138
+ # colorscale=[[0, start_color], [1, end_color]],
139
+ # n_colors=num_colors
140
+ # )
141
+ # return custom_colors
142
+
143
+ def plot_comparison_chart(df,metric,custom_colors):
144
+ # # print(metric)
145
+ # # print(custom_colors)
146
+ custom_colors = [
147
+ "#4169E1", # Royal Blue
148
+ "#ADD8E6", # Light Blue
149
+ "#FF7F50" , # Coral
150
+ "#87CEEB", # Sky Blue
151
+ "#FA8072", # Salmon
152
+ "#1E90FF", # Dodger Blue
153
+
154
+ "#00008B" ,
155
+ "#F08080", # Light Coral
156
+
157
+ "#FF8C00", # Dark Orange
158
+ "#FFA500", # Orange
159
+
160
+ ]
161
+ # Create traces for each column
162
+ traces = []
163
+ for i,column in enumerate(df.columns):
164
+ # # print(i)
165
+ # # print(custom_colors[i])
166
+ traces.append(go.Bar(
167
+ x=df.index,
168
+ y=df[column],
169
+ name=column,
170
+ text=df[column].apply(numerize), # Adding text for each point
171
+ textposition='auto',
172
+ hoverinfo='x+y+text',
173
+ marker_color = custom_colors[i]
174
+ ))
175
+
176
+ # Create the layout
177
+ layout = go.Layout(
178
+ title='Comparing '+ metric,
179
+ xaxis_title="Channels",
180
+ yaxis_title=metric,
181
+ barmode='group'
182
+ )
183
+
184
+ # Create the figure
185
+ fig = go.Figure(data=traces, layout=layout)
186
+
187
+ fig.update_layout(
188
+
189
+ legend=dict(
190
+ orientation="h", # Horizontal orientation
191
+ yanchor="top", # Anchor the legend at the top
192
+ y=-0.45, # Position the legend below the plot area
193
+ xanchor="center", # Center the legend horizontally
194
+ x=0.5 # Center the legend on the x-axis
195
+ )
196
+ )
197
+
198
+ return fig
199
+
200
+ def save_ppt_file(fig1,fig2,fig3):
201
+
202
+ # Initialize PowerPoint presentation
203
+ prs = Presentation()
204
+ # Helper function to add Plotly figure to slide
205
+ def add_plotly_chart_to_slide(slide, fig, left, top, width, height):
206
+ img_stream = BytesIO()
207
+ pio.write_image(fig, img_stream, format='png')
208
+ slide.shapes.add_picture(img_stream, left, top, width, height)
209
+
210
+ slide_1 = prs.slides.add_slide(prs.slide_layouts[6])
211
+ # title_1 = slide_1.shapes.title
212
+ # title_1.text = "Comparing Spends"
213
+
214
+ add_plotly_chart_to_slide(slide_1, fig1, Inches(0), Inches(0.25), width=Inches(10), height=Inches(6))
215
+
216
+ slide_2 = prs.slides.add_slide(prs.slide_layouts[6])
217
+ # title_2 = slide_2.shapes.title
218
+ # title_2.text = "Comparing Contributions"
219
+ add_plotly_chart_to_slide(slide_2, fig2, Inches(0), Inches(0.25), width=Inches(10), height=Inches(6))
220
+
221
+
222
+ slide_3 = prs.slides.add_slide(prs.slide_layouts[6])
223
+ # title_3 = slide_3.shapes.title
224
+ # title_3.text = "Comparing Efficiency"
225
+ add_plotly_chart_to_slide(slide_3, fig3, Inches(0), Inches(0.25), width=Inches(10), height=Inches(6))
226
+
227
+ ppt_stream = BytesIO()
228
+ prs.save(ppt_stream)
229
+ ppt_stream.seek(0)
230
+
231
+ return ppt_stream.getvalue()
232
+
233
+ def create_comparison_plots():
234
+ # comparison_scenarios_df()
235
+ spends_df, prospects_df, efficiency_df = comparison_scenarios_df()
236
+ # st.dataframe(spends_df)
237
+ blue = "#0000FF" # Blue
238
+ green = "#00FF00" # Green
239
+ red = "#FF0000" # Red
240
+
241
+ custom_colors = generate_color_gradient(blue, red, spends_df.shape[1])
242
+ st.plotly_chart(plot_comparison_chart(spends_df,"Spends",custom_colors),use_container_width=True)
243
+ st.plotly_chart(plot_comparison_chart(prospects_df,"Contributions",custom_colors),use_container_width=True)
244
+ st.plotly_chart(plot_comparison_chart(efficiency_df,"Efficiency",custom_colors),use_container_width=True)
245
+
246
+ fig1 = plot_comparison_chart(spends_df,"Spends",custom_colors)
247
+ fig2 = plot_comparison_chart(prospects_df,"Contributions",custom_colors)
248
+ fig3 = plot_comparison_chart(efficiency_df,"Efficiency",custom_colors)
249
+
250
+ ppt_file = save_ppt_file(fig1,fig2,fig3)
251
+ # Add a download button
252
+ st.download_button(
253
+ label="Download Comparision Analysis",
254
+ data=ppt_file,
255
+ file_name="MMM_Scenario_Comparision.pptx",
256
+ mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
257
+ )
258
+
259
+
260
+ def create_scenario_summary(scenario_dict):
261
+ summary_rows = []
262
+ actual_total_spends = scenario_dict.get('actual_total_spends'),
263
+ modified_total_spends = scenario_dict.get('modified_total_spends'),
264
+ actual_total_sales = scenario_dict.get('actual_total_sales'),
265
+ modified_total_sales = scenario_dict.get('modified_total_sales')
266
+ # st.write(modified_total_spends[0])
267
+ # st.write(actual_total_spends[0])
268
+ # st.write(modified_total_sales)
269
+ # st.write(actual_total_sales[0])
270
+ # st.write(modified_total_spends[0])
271
+ for channel_dict in scenario_dict['channels']:
272
+ # st.write(channel_dict['name'])
273
+ name_mod = channel_name_formating(channel_dict['name'])
274
+ summary_rows.append([name_mod,
275
+ channel_dict.get('actual_total_spends') * channel_dict.get('conversion_rate'),
276
+ channel_dict.get('modified_total_spends') * channel_dict.get('conversion_rate'),
277
+ channel_dict.get('actual_total_sales') ,
278
+ channel_dict.get('modified_total_sales'),
279
+ # channel_dict.get('modified_total_sales')/modified_total_spends[0],
280
+ # channel_dict.get('modified_total_sales')/modified_total_spends[0]
281
+
282
+ # 1,2
283
+ (channel_dict.get('actual_total_sales') /actual_total_sales[0])/(channel_dict.get('actual_total_spends') /actual_total_spends[0] ),
284
+ (channel_dict.get('modified_total_sales') /modified_total_sales )/(channel_dict.get('modified_total_spends') /modified_total_spends[0] )
285
+ # # # channel_dict.get('actual_mroi'),
286
+ # channel_dict.get('modified_mroi'),
287
+ # channel_dict.get('actual_total_spends') * channel_dict.get('conversion_rate') / channel_dict.get('actual_total_sales'),
288
+ # channel_dict.get('modified_total_spends') * channel_dict.get('conversion_rate') / channel_dict.get('modified_total_sales')
289
+ ])
290
+
291
+ summary_rows.append(['Total',
292
+ scenario_dict.get('actual_total_spends'),
293
+ scenario_dict.get('modified_total_spends'),
294
+ scenario_dict.get('actual_total_sales'),
295
+ scenario_dict.get('modified_total_sales'),
296
+ 1.0,
297
+ 1.0
298
+ # scenario_dict.get('actual_total_sales') / scenario_dict.get('actual_total_spends'),
299
+ # scenario_dict.get('modified_total_sales') / scenario_dict.get('modified_total_spends'),
300
+ # '-',
301
+ # '-',
302
+ # scenario_dict.get('actual_total_spends') / scenario_dict.get('actual_total_sales'),
303
+ # scenario_dict.get('modified_total_spends') / scenario_dict.get('modified_total_sales')
304
+ ])
305
+
306
+ adf = pd.DataFrame(summary_rows)
307
+ # st.write(adf.columns)
308
+
309
+ adf.columns = ["1","2","3","4","5","6","7"]
310
+ adf.index = adf["1"].to_list() #["1","2","3","4","5","6","7","8","9","10","11","12","13","14"]
311
+ adf.drop(columns= ["1"],inplace= True)
312
+ # columns_index = pd.MultiIndex.from_product([[''],['Channel']], names=["",""])
313
+ # columns_index = columns_index.append(pd.MultiIndex.from_product([['Spends','Prospects',"Efficiency"],['Actual','Simulated']], names=["",""]))
314
+ columns_index = pd.MultiIndex.from_product([['Spends','Prospects',"Efficiency"],['Actual','Simulated']], names=["",""])
315
+ adf.columns = columns_index
316
+ return adf # pd.DataFrame(summary_rows, columns=columns_index)
317
+
318
+
319
+
320
+ def summary_df_to_worksheet(df, ws):
321
+ heading_fill = PatternFill(fill_type='solid',start_color='FFFFFFFF',end_color='FFFFFFFF')
322
+
323
+ # Define border style
324
+ border_style = Border(
325
+ left=Side(border_style='thin', color='00000000'),
326
+ right=Side(border_style='thin', color='00000000'),
327
+ top=Side(border_style='thin', color='00000000'),
328
+ bottom=Side(border_style='thin', color='00000000')
329
+ )
330
+ number_format = '0.00'
331
+ for j,header in enumerate(df.columns.values):
332
+ col = j + 1
333
+ for i in range(1,3):
334
+ ws.cell(row=i, column=j + 1, value=header[i - 1]).font = Font(bold=True, color='00000000')
335
+ ws.cell(row=i,column=j+1).fill = heading_fill
336
+ # ws.cell.border = border_style
337
+ # if col > 1 and (col - 6)%5==0:
338
+ # ws.merge_cells(start_row=1, end_row=1, start_column = col-3, end_column=col)
339
+ # ws.cell(row=1,column=col).alignment = Alignment(horizontal='center')
340
+ # # ws.cell.border = border_style
341
+ # Apply borders to all cells, including empty cells
342
+ for row in ws.iter_rows():
343
+ for cell in row:
344
+ cell.border = border_style
345
+
346
+ for i,row in enumerate(df.itertuples()):
347
+ for j,value in enumerate(row):
348
+ if j == 0:
349
+ continue
350
+ # elif (j-2)%4 == 0 or (j-3)%4 == 0:
351
+ # ws.cell(row=i+3, column = j, value=value)
352
+ # # cell.border = border_style
353
+ # # .number_format = '$#,##0.0'
354
+ # if isinstance(value, (int, float)):
355
+ # cell.number_format = number_format
356
+ else:
357
+ ws.cell(row=i+3, column = j, value=value)
358
+ # cell.border = border_style
359
+ if isinstance(value, (int, float)):
360
+ cell.number_format = '$#,##0.0'
361
+ # cell.number_format = number_format
362
+ # Auto-size columns
363
+ for col in ws.columns:
364
+ max_length = 15
365
+ column = col[0].column_letter
366
+ for cell in col:
367
+ try:
368
+ if len(str(cell.value)) > max_length:
369
+ max_length = len(cell.value)
370
+ except:
371
+ pass
372
+ adjusted_width = (max_length + 2)
373
+ ws.column_dimensions[column].width = adjusted_width
374
+
375
+ from openpyxl.utils import get_column_letter
376
+ from openpyxl.styles import Font, PatternFill
377
+ from openpyxl.styles import PatternFill, Font, Alignment, Border, Side
378
+ import logging
379
+
380
+ def scenario_df_to_worksheet(df, ws):
381
+ heading_fill = PatternFill(start_color='FF11B6BD', end_color='FF11B6BD', fill_type='solid')
382
+
383
+ for j, header in enumerate(df.columns.values):
384
+ cell = ws.cell(row=1, column=j + 1, value=header)
385
+ cell.font = Font(bold=True, color='FF11B6BD')
386
+ cell.fill = heading_fill
387
+
388
+ for i, row in enumerate(df.itertuples()):
389
+ for j, value in enumerate(row[1:], start=1): # Start from index 1 to skip the index column
390
+ try:
391
+ cell = ws.cell(row=i + 2, column=j, value=value)
392
+ if isinstance(value, (int, float)):
393
+ cell.number_format = '$#,##0.0'
394
+ elif isinstance(value, str):
395
+ cell.value = value[:32767]
396
+ else:
397
+ cell.value = str(value)
398
+ except ValueError as e:
399
+ logging.error(f"Error assigning value '{value}' to cell {get_column_letter(j)}{i+2}: {e}")
400
+ cell.value = None # Assign None to the cell where the error occurred
401
+
402
+ return ws
403
+
404
+
405
+
406
+
407
+
408
+
409
+ def download_scenarios():
410
+ """
411
+ Makes a excel with all saved scenarios and saves it locally
412
+ """
413
+ ## create summary page
414
+ if len(scenarios_to_download) == 0:
415
+ return
416
+ wb = Workbook()
417
+ wb.iso_dates = True
418
+ wb.remove(wb.active)
419
+ st.session_state['xlsx_buffer'] = io.BytesIO()
420
+ summary_df = None
421
+ ## # # print(scenarios_to_download)
422
+ for scenario_name in scenarios_to_download:
423
+ scenario_dict = st.session_state['saved_scenarios'][scenario_name]
424
+ _spends = []
425
+ column_names = ['Date']
426
+ _sales = None
427
+ dates = None
428
+ summary_rows = []
429
+ for channel in scenario_dict['channels']:
430
+ if dates is None:
431
+ dates = channel.get('dates')
432
+ _spends.append(dates)
433
+ if _sales is None:
434
+ _sales = channel.get('modified_sales')
435
+ else:
436
+ _sales += channel.get('modified_sales')
437
+ _spends.append(channel.get('modified_spends') * channel.get('conversion_rate'))
438
+ column_names.append(channel.get('name'))
439
+
440
+ name_mod = channel_name_formating(channel['name'])
441
+ summary_rows.append([name_mod,
442
+ channel.get('modified_total_spends') * channel.get('conversion_rate') ,
443
+ channel.get('modified_total_sales'),
444
+ # channel.get('modified_total_sales') / channel.get('modified_total_spends') * channel.get('conversion_rate'),
445
+ # channel.get('modified_mroi'),
446
+ # channel.get('modified_total_sales') / channel.get('modified_total_spends') * channel.get('conversion_rate')
447
+ ])
448
+ _spends.append(_sales)
449
+ column_names.append('NRPU')
450
+ scenario_df = pd.DataFrame(_spends).T
451
+ scenario_df.columns = column_names
452
+ ## write to sheet
453
+ # ws = wb.create_sheet(scenario_name)
454
+ # scenario_df_to_worksheet(scenario_df, ws)
455
+ summary_rows.append(['Total',
456
+ scenario_dict.get('modified_total_spends') ,
457
+ scenario_dict.get('modified_total_sales'),
458
+ # scenario_dict.get('modified_total_sales') / scenario_dict.get('modified_total_spends'),
459
+ # '-',
460
+ # scenario_dict.get('modified_total_spends') / scenario_dict.get('modified_total_sales')
461
+ ])
462
+ columns_index = pd.MultiIndex.from_product([[''],['Channel']], names=["first", "second"])
463
+ columns_index = columns_index.append(pd.MultiIndex.from_product([[scenario_name],['Spends','Prospects',
464
+ # 'ROI','MROI','Spends per NRPU'
465
+ ]], names=["first", "second"]))
466
+ if summary_df is None:
467
+ summary_df = pd.DataFrame(summary_rows, columns = columns_index)
468
+ summary_df = summary_df.set_index(('','Channel'))
469
+ else:
470
+ _df = pd.DataFrame(summary_rows, columns = columns_index)
471
+ _df = _df.set_index(('','Channel'))
472
+ summary_df = summary_df.merge(_df, left_index=True, right_index=True)
473
+ ws = wb.create_sheet('Summary',0)
474
+ summary_df_to_worksheet(summary_df.reset_index(), ws)
475
+ wb.save(st.session_state['xlsx_buffer'])
476
+ st.session_state['disable_download_button'] = False
477
+
478
+ def disable_download_button():
479
+ st.session_state['disable_download_button'] =True
480
+
481
+ def transform(x):
482
+ if x.name == ("",'Channel'):
483
+ return x
484
+ elif x.name[0] == 'Efficiency' or x.name[0] == 'MROI':
485
+ return x.apply(lambda y : y if isinstance(y,str) else decimal_formater(format_numbers(y,include_indicator=False,n_decimals=2),n_decimals=2))
486
+ else:
487
+ return x.apply(lambda y : y if isinstance(y,str) else format_numbers(y))
488
+
489
+ def delete_scenario():
490
+ if selected_scenario in st.session_state['saved_scenarios']:
491
+ del st.session_state['saved_scenarios'][selected_scenario]
492
+ with open('../saved_scenarios.pkl', 'wb') as f:
493
+ pickle.dump(st.session_state['saved_scenarios'],f)
494
+
495
+ def load_scenario():
496
+ if selected_scenario in st.session_state['saved_scenarios']:
497
+ st.session_state['scenario'] = class_from_dict(selected_scenario_details)
498
+
499
+
500
+
501
+ authenticator = st.session_state.get('authenticator')
502
+ if authenticator is None:
503
+ authenticator = load_authenticator()
504
+
505
+ name, authentication_status, username = authenticator.login('Login', 'main')
506
+ auth_status = st.session_state.get('authentication_status')
507
+
508
+ if auth_status == True:
509
+ is_state_initiaized = st.session_state.get('initialized',False)
510
+ if not is_state_initiaized:
511
+ ## # # print("Scenario page state reloaded")
512
+ initialize_data(target_file = "Overview_data_test_panel@#prospects.xlsx")
513
+
514
+
515
+ saved_scenarios = st.session_state['saved_scenarios']
516
+
517
+
518
+ if len(saved_scenarios) ==0:
519
+ st.header('No saved scenarios')
520
+
521
+ else:
522
+
523
+ with st.sidebar:
524
+ with st.expander('View Scenario Details'):
525
+ st.markdown("""<hr>""", unsafe_allow_html=True)
526
+ selected_scenario = st.selectbox('Select the scenario',list(saved_scenarios.keys()))
527
+ # selected_scenario = st.radio(
528
+ # 'Pick a scenario to view details',
529
+ # list(saved_scenarios.keys())
530
+ # )
531
+ st.button('Delete scenario', on_click=delete_scenario)
532
+ with st.expander('Download Scenario'):
533
+ st.markdown("""<hr>""", unsafe_allow_html=True)
534
+ scenarios_to_download = st.multiselect('Select scenarios to download',
535
+ list(saved_scenarios.keys()))
536
+
537
+ st.button('Prepare download',on_click=download_scenarios)
538
+ st.download_button(
539
+ label="Download Scenarios",
540
+ data=st.session_state['xlsx_buffer'].getvalue(),
541
+ file_name="scenarios.xlsx",
542
+ mime="application/vnd.ms-excel",
543
+ disabled= st.session_state['disable_download_button'],
544
+ on_click= disable_download_button
545
+ )
546
+ with st.expander('Compare Scenarios'):
547
+ st.markdown("""<hr>""", unsafe_allow_html=True)
548
+ scenarios_to_compare = st.multiselect('Select scenarios to compare',
549
+ list(saved_scenarios.keys()))
550
+ st.button('Compare')
551
+
552
+
553
+ column_1, column_2,column_3 = st.columns((6,1,1))
554
+ with column_1:
555
+ st.markdown(f'<span style="font-size:28px"><strong>Selected Scenario:</strong> {selected_scenario}</span>', unsafe_allow_html=True)
556
+ # st.header(f"Selected Scenario: {selected_scenario}")
557
+ # with column_3:
558
+ # st.write("")
559
+ # st.button('Delete scenario', on_click=delete_scenario)
560
+ # with column_3:
561
+ # st.button('Load Scenario', on_click=load_scenario)
562
+
563
+ selected_scenario_details = saved_scenarios[selected_scenario]
564
+
565
+ pd.set_option('display.max_colwidth', 100)
566
+ # st.table(create_scenario_summary(selected_scenario_details))
567
+ # st.table(create_scenario_summary(selected_scenario_details).transform(transform))
568
+ adf = create_scenario_summary(selected_scenario_details).transform(transform)
569
+ # adf1 = adf[('Spends', 'Actual'),
570
+ # ( 'Spends', 'Simulated'),
571
+ # ( 'Prospects','Actual'),
572
+ # ( 'Prospects', 'Simulated')].transform(transform)
573
+ # adf2 = adf[('Efficiency', 'Actual'),
574
+ # ('Efficiency', 'Simulated')].round(2)
575
+ # st.write(adf.columns)
576
+ # adf = adf.set_index([('', 'Channel')])#, inplace=True)
577
+ # st.table(adf)
578
+ st.markdown(adf.style.set_table_styles(
579
+ [
580
+ # {
581
+ # 'selector': 'th',
582
+ # 'props': [('background-color', '#1167bd')]
583
+ # },
584
+ # {
585
+ # 'selector' : 'tr:nth-child(even)',
586
+ # 'props' : [('background-color', '#11B6BD')]
587
+ # }
588
+ ]).to_html(),unsafe_allow_html=True)
589
+ st.markdown("<br><br>", unsafe_allow_html=True)
590
+
591
+ with st.expander('Scenario Comparison'):
592
+ st.header("Scenario Comparison")
593
+ if len(scenarios_to_compare)== 0:
594
+ st.write("")
595
+ else:
596
+ create_comparison_plots()
597
+
598
+ elif auth_status == False:
599
+ st.error('Username/Password is incorrect')
600
+
601
+ if auth_status != True:
602
+ try:
603
+ username_forgot_pw, email_forgot_password, random_password = authenticator.forgot_password('Forgot password')
604
+ if username_forgot_pw:
605
+ st.success('New password sent securely')
606
+ # Random password to be transferred to user securely
607
+ elif username_forgot_pw == False:
608
+ st.error('Username not found')
609
+ except Exception as e:
610
+ st.error(e)
611
+
612
+
613
+
614
+
615
+
616
+ # create_comparison_plots()
pages/5_Glossary.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ # st.set_page_config(
4
+ # layout="wide"
5
+ # )
6
+
7
+ def glossary_run():
8
+ st.header("Glossary")
9
+ with st.expander("Model MMM Terminology"):
10
+ st.subheader("Glossary of MMM Terminology")
11
+ st.write("**• Model R-squared \(R\)\:** This is a statistical measure used to determine the percentage of variation in the dependent variable that the independent variables explain collectively. It ranges between 0 and 1, where 1 indicates a perfect fit and 0 indicates no linear relationship. An R2 greater than 0.8 usually indicates a great model fit.")
12
+
13
+ st.write("**• Mean Absolute Percentage Error \(MAPE\):** This is a measure used to determine the accuracy of a predictive model. It calculates the average absolute percentage difference between the actual and predicted values, expressing the result as a percentage to provide a sense of scale for the error.")
14
+
15
+ st.write("**• Media & Baseline Elasticity:** It refers to the percentage change in the number of prospects in response to a percentage change in a marketing input \(media channel spends\) or a baseline factor \(like seasonality. macro factors, competitors spending, etc.\). It is a measure of the responsiveness of the number of prospects to changes in the marketing input or the baseline factor")
16
+
17
+ st.write("**• Media Half-Life:** This represents the time it takes for a media spend's impact to reduce to half of its initial impact. It is a key aspect of media decay rates, which represent how the effect of advertising diminishes over time \(in weeks\). This term refers to a curve that illustrates the relationship between media spend and the resulting number of prospects.")
18
+
19
+ st.write("**• Support:** Equivalent to Impression or Click depending on the media channel.")
20
+
21
+ st.write("**• Contribution Share:** Unit is %. It refers to the percentage contribution of a specific marketing channel to the number of prospects. It is calculated by dividing the contribution from a particular channel by the total number of prospects from all media channels \(not including base contributions\).")
22
+
23
+ st.write("**• Spend Share:** Unit is %. It refers to the percentage of the total marketing budget that is allocated to a specific marketing channel. It is calculated by dividing the amount spent on a particular channel by the total marketing spend")
24
+
25
+ st.write("**• Support Share:** Unit is %. It refers to the percentage of the total media impression that is allocated to a specific marketing channel. It is calculated by dividing support on a particular channel by the total marketing spend")
26
+
27
+ st.write("**• Efficiency Index:** it is a metric that measures the cost-effectiveness of a campaign. It is calculated by dividing Contribution Share by Spend Share. An efficiency index above 1 suggests that a channel is more cost-effective than the benchmark, while an efficiency index below 1 suggests it is less cost-effective. The higher the efficiency index, the more cost-effective its channel is")
28
+
29
+ st.write("**• Effectiveness Index:** It is a metric that measures how well a particular marketing channel is performing relative to its support/impression. It is calculated by dividing the Contribution Share by the Spend Share for each channel")
30
+
31
+ st.write("**• Estimated CPM \(Cost Per Thousand Impressions\):** This is an estimation of the cost for every thousand impressions \(or views\) of its advertisement via that media channel. The default values are generated from historical averages.")
32
+
33
+ st.write("**• Estimated CPC \(Cost Per Click\):** This is an estimation of the cost for each time someone clicks on its advertisement via that media channel. The default values are generated from historical averages.")
34
+ with st.expander("Deployment Plan"):
35
+ st.image(r"image (2).png")
36
+ glossary_run()
requirements.txt ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ altair == 4.2.0
2
+ attrs == 23.1.0
3
+ bcrypt == 4.0.1
4
+ blinker == 1.6.2
5
+ cachetools == 5.3.1
6
+ certifi == 2023.7.22
7
+ charset-normalizer == 3.2.0
8
+ click == 8.1.7
9
+ colorama == 0.4.6
10
+ contourpy == 1.1.1
11
+ cycler == 0.11.0
12
+ dacite == 1.8.1
13
+ entrypoints == 0.4
14
+ et-xmlfile == 1.1.0
15
+ extra-streamlit-components == 0.1.56
16
+ fonttools == 4.42.1
17
+ gitdb == 4.0.10
18
+ GitPython == 3.1.35
19
+ htmlmin == 0.1.12
20
+ idna == 3.4
21
+ ImageHash == 4.3.1
22
+ importlib-metadata == 6.8.0
23
+ importlib-resources == 6.1.0
24
+ Jinja2 == 3.1.2
25
+ joblib == 1.3.2
26
+ jsonschema == 4.19.0
27
+ jsonschema-specifications== 2023.7.1
28
+ kaleido == 0.2.1
29
+ kiwisolver == 1.4.5
30
+ markdown-it-py == 3.0.0
31
+ MarkupSafe == 2.1.3
32
+ matplotlib == 3.7.0
33
+ mdurl == 0.1.2
34
+ networkx == 3.1
35
+ numerize == 0.12
36
+ numpy == 1.23.5
37
+ openpyxl>=3.1.0
38
+ packaging == 23.1
39
+ pandas == 1.5.2
40
+ pandas-profiling == 3.6.6
41
+ patsy == 0.5.3
42
+ phik == 0.12.3
43
+ Pillow == 10.0.0
44
+ pip == 23.2.1
45
+ plotly == 5.11.0
46
+ protobuf == 3.20.3
47
+ pyarrow == 13.0.0
48
+ pydantic == 1.10.13
49
+ pydeck == 0.8.1b0
50
+ Pygments == 2.16.1
51
+ PyJWT == 2.8.0
52
+ Pympler == 1.0.1
53
+ pyparsing == 3.1.1
54
+ python-dateutil == 2.8.2
55
+ python-decouple == 3.8
56
+ pytz == 2023.3.post1
57
+ PyWavelets == 1.4.1
58
+ PyYAML == 6.0.1
59
+ referencing == 0.30.2
60
+ requests == 2.31.0
61
+ rich == 13.5.2
62
+ rpds-py == 0.10.2
63
+ scikit-learn == 1.1.3
64
+ scipy == 1.9.3
65
+ seaborn == 0.12.2
66
+ semver == 3.0.1
67
+ setuptools == 68.1.2
68
+ six == 1.16.0
69
+ smmap == 5.0.0
70
+ statsmodels == 0.14.0
71
+ streamlit == 1.16.0
72
+ streamlit-aggrid == 0.3.4.post3
73
+ streamlit-authenticator == 0.2.1
74
+ streamlit-pandas-profiling== 0.1.3
75
+ sweetviz == 2.2.1
76
+ tangled-up-in-unicode == 0.2.0
77
+ tenacity == 8.2.3
78
+ threadpoolctl == 3.2.0
79
+ toml == 0.10.2
80
+ toolz == 0.12.0
81
+ tornado == 6.3.3
82
+ tqdm == 4.66.1
83
+ typeguard == 2.13.3
84
+ typing_extensions == 4.7.1
85
+ tzdata == 2023.3
86
+ tzlocal == 5.0.1
87
+ urllib3 == 2.0.4
88
+ validators == 0.22.0
89
+ visions == 0.7.5
90
+ watchdog == 3.0.0
91
+ wheel == 0.41.2
92
+ wordcloud == 1.9.2
93
+ ydata-profiling == 4.5.1
94
+ zipp == 3.16.2
95
+ python-pptx
96
+ orca
response_curves_input_file.csv ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,MAT,tv_broadcast_spend,tv_cable_spend,stream_video_spend,disp_prospect_spend,disp_retarget_spend,olv_spend,social_prospect_spend,social_retarget_spend,search_brand_spend,search_nonbrand_spend,cm_spend,audio_spend,email_spend,Broadcast TV_Prospects,Cable TV_Prospects,Connected & OTT TV_Prospects,Video_Prospects,Display Prospecting_Prospects,Display Retargeting_Prospects,Social Prospecting_Prospects,Social Retargeting_Prospects,Search Brand_Prospects,Search Non-brand_Prospects,Digital Partners_Prospects,Audio_Prospects,Email_Prospects,email_imp,tv_broadcast_grp,tv_cable_grp,stream_video_imp,olv_imp,disp_prospect_imp,disp_retarget_imp,social_prospect_imp,social_retarget_imp,search_brand_imp,search_nonbrand_imp,audio_imp,Trend,Seasonality,Unemployment,Competition,Base_0,Y_hat,Y
2
+ 2/27/2022,Previous Year,253149,781045,125074.2227,54694.7903,48614.8483,158270.8903,99387.6697,34126.5203,169663.4355,1018478.108,358612.1106,71620.65,0,605.7688941,880.7115151,135.0516981,208.2711327,19.41746001,297.0007496,345.010799,51.00935797,214.3019417,892.607461,833.4551364,316.7036224,0,0,6501400,27805200,6962021,7324755,5253400,2476706,7947893,2499918,118423,2906350,6521578,14675.60284,0.910427151,337.9781516,-2687.890429,4915.261967,7364.659458,7848
3
+ 3/6/2022,Previous Year,172240,118799,114926.2572,61691.4621,50759.0208,145472.5979,108619.6589,40377.359,172883.1612,1056874.218,352654.3548,104089.32,0,779.587861,837.4491512,157.5004969,207.4753074,79.15177069,392.480332,343.428751,50.4354065,219.5135831,875.611235,819.5548137,315.3451715,0,0,4083800,5027600,6389518,8035186,9173404,3151490,8452405,2221844,120664,2858165,9021344,14686.18011,0.956949264,336.1986193,-2808.001348,5170.151637,7775.882788,8383
4
+ 3/13/2022,Previous Year,133070,684154,126244.2042,54248.7133,59587.5653,133415.8917,113438.9101,42135.129,169341.1286,948207.014,352654.3548,89419.84,0,864.7806971,954.5658374,187.947124,221.713362,76.2604722,468.6212166,366.996612,67.83612655,234.9089159,901.5223839,875.796913,336.9854082,0,0,3445400,23532100,7128473,7481995,8223833,3482608,7759209,2540900,117969,2739628,7908541,14696.75785,1.038429076,365.0871448,-3038.414156,5614.407052,8499.01511,8015
5
+ 3/20/2022,Previous Year,107525,117392,124944.9776,35301.9351,44023.1238,143263.0604,118489.7299,45682.1629,162336.685,918017.1961,352654.3548,95743.91,0,731.3285906,936.5859186,196.7562215,227.2802865,62.379592,339.6859962,376.2114027,82.22335436,240.9831858,932.7780942,897.7869942,345.4468683,0,0,1568200,5738800,7051319,8324282,7388989,2483714,9879973,2770852,127779,2768673,8221354,14707.33604,1.013456197,356.5637272,-2963.404176,5483.331674,8245.937729,8046
6
+ 3/27/2022,Previous Year,181507,869840,153316.3619,23168.6555,27715.6219,161021.1805,100884.2514,43556.2893,153511.8983,895973.8566,332300.3011,112738.67,0,686.1206578,918.340495,209.7801073,208.7921837,27.39101731,164.8588646,345.6085063,79.3408774,221.3853364,991.6264718,789.6958012,317.3467101,0,0,2707400,29952600,8812928,9920308,5146514,1361260,9452096,2825988,123822,3274892,9528756,14717.91468,0.932822774,328.4305777,-2734.671585,5050.692631,7604.738652,7645
7
+ 4/3/2022,Previous Year,255489,818061,210851.03,17834.6126,30620.5585,120571.542,62211.6901,37726.2686,172955.6522,812147.8732,281415.1667,109759.87,0,690.8365006,809.1925488,228.8269719,180.9403061,22.82948094,190.2177151,299.5059862,53.00895811,191.8827057,1098.987071,605.7673405,275.0141765,0,0,3846600,29123900,11969429,6794224,5308785,1827662,5126089,2405410,129790,4391323,9272330,14728.49379,0.848751045,307.6239164,-2506.786373,4598.796328,7046.643634,6822
8
+ 4/10/2022,Previous Year,258458,66991,200740.434,42305.0386,29582.5014,113284.3507,63600.74,39341.1182,174865.093,688051.4547,281415.1667,102978.95,0,720.8362641,735.4593072,225.7303976,173.9216886,24.71429802,139.7027908,287.8882436,44.87884693,184.4272411,984.3838731,582.2698163,264.3464426,0,0,4435900,2841600,11451763,6562442,5642426,1405186,4963382,2273471,124587,4030572,8746138,14739.07335,0.780330674,283.0285834,-2304.556616,4231.11059,6578.141768,6074
9
+ 4/17/2022,Previous Year,263076,606184,180483.3354,57034.958,30415.228,109745.4578,59852.9494,37701.5391,179988.2767,814446.911,281415.1667,88323.07,0,775.4075191,796.3286979,227.1361474,184.1782682,20.09658828,185.1578527,304.8657049,49.54791165,195.3077905,992.5354147,616.6076663,279.9348206,0,0,4075400,20427400,10361165,6502361,4913095,1751584,4824635,2348779,126607,3800406,7603572,14749.65336,0.85017898,308.5841504,-2520.906267,4613.151262,7027.933528,6709
10
+ 4/24/2022,Previous Year,250214,65320,141072.1122,73953.7058,21631.9718,109181.4446,58344.9797,36928.8089,183194.4077,1086859.594,281415.1667,94202.12,0,835.5742747,795.138986,203.775006,194.3528204,30.77660161,197.2930056,321.7073877,54.16304355,206.1241222,1127.671193,650.6708965,295.3997591,0,0,5134800,3756400,8017694,7170056,5992850,1757875,4632566,2391572,133812,4153311,8051284,14760.23384,0.911268737,330.9947825,-2698.845226,4948.17701,7492.973662,7406
11
+ 5/1/2022,Previous Year,172078,536735,176823.3416,40553.7511,21528.0108,89861.4638,45399.1102,31588.1625,192717.6062,1142770.685,248280.9677,95382,0,778.4072046,800.3858887,209.6706691,187.8029139,14.68086209,117.0588368,310.8654904,48.92250172,199.1598609,1522.512401,573.2443965,285.4445468,0,0,2391900,19407400,9676729,6979289,4111226,1104257,4145120,2293819,125728,6345501,8139850,14770.81477,0.931139949,329.0164217,-2763.791971,5059.701895,7673.081919,7800
12
+ 5/8/2022,Previous Year,289594,865224,171052.3668,31438.0549,24653.4823,79504.5508,44852.6394,32437.9314,218107.6945,991247.1823,248280.9677,91000.57,0,888.1079123,918.5182742,230.406251,207.458539,6.824600634,105.0858789,343.4009675,57.14979371,220.0015126,1502.533433,633.2406986,315.3190743,0,0,4998900,29237000,9335996,5500316,2775447,923620,3897909,2380118,127009,5475181,7801497,14781.39616,1.009487008,356.9557265,-2996.518776,5489.359943,8277.84383,7728
13
+ 5/15/2022,Previous Year,259505,130778,156111.0981,40856.3032,23271.2593,87131.4059,46964.72,39315.3417,189210.2066,1305416.166,248280.9677,84276.3,0,942.8699373,927.5320449,231.7409952,219.2881419,5.789528794,103.0402573,362.9822054,58.18594974,232.5560247,1604.383918,669.3490323,333.2967868,0,0,4563300,5689000,8614494,7306658,2644020,866056,3911441,2320404,129426,5547033,7266756,14791.978,1.053720949,372.8636352,-3120.728169,5733.995987,8677.146276,8553
14
+ 5/22/2022,Previous Year,170131,487233,141560.8242,46587.2665,15802.0639,124739.5882,53052.1502,41359.6906,182646.3961,1100956.072,248280.9677,72062.14,0,885.4667828,886.484453,205.2506739,206.7666081,10.84383167,60.95975874,342.2556214,44.88531703,219.249405,1285.973994,631.1286493,314.2363601,0,0,3837500,17671600,7951908,11366594,3739728,558619,4008712,2069851,122868,4521066,6314917,14802.56029,0.960881656,340.255304,-2869.508127,5232.536412,7796.785045,7985
15
+ 5/29/2022,Previous Year,231788,67361,162521.2911,54793.5324,17791.37,155836.591,61764.2001,37530.7416,181586.3546,945174.1624,232758.129,100595.57,0,872.1263477,819.8747129,211.6585103,203.0097861,32.79210764,170.5377143,336.0370474,32.71797255,215.2991394,1159.99767,590.7548479,308.5578319,0,0,4433950,3088000,8866030,15397724,6226749,1504202,4431245,1769700,132473,4077070,8545627,14813.14305,0.938982425,332.7383382,-2820.569692,5116.938515,7582.47085,7079
16
+ 6/5/2022,Previous Year,293445,478193,211309.1498,56885.2966,18616.703,146769.2013,109459.0296,39077.581,194110.2621,961289.855,221116,108011.65,0,850.0419903,833.2096897,239.4503592,196.9778946,30.43141305,86.116707,326.0526075,33.33021252,208.8987866,1289.817117,551.8094443,299.3899667,0,0,5030400,18438400,11110777,13418380,5800991,792576,12123372,1854848,128873,4819112,9111446,14823.72624,0.933980932,331.2024636,-2815.801622,5093.319428,7554.246458,7829
17
+ 6/12/2022,Previous Year,368290,556103,264401.3059,62913.1718,31719.2575,155932.3206,155854.4295,39513.7406,210540.3029,875163.7963,221116,96372.9,0,899.3901532,898.3532455,305.2964146,208.0552874,37.41568812,114.7826432,344.3887402,41.13349708,220.6385363,1252.42105,582.8414035,316.2265328,0,0,5253300,19930600,14265260,14446793,6268878,1010679,19784676,2018338,127149,4343514,8202807,14834.3099,0.977680118,346.9463266,-2918.719411,5335.432733,7984.602841,8574
18
+ 6/19/2022,Previous Year,75811,72120,287842.2427,63572.4839,37819.1568,166389.6139,157972.8297,42093.21968,218115.79,876506.58,221116,88684,0,890.7498196,863.113055,347.5208084,211.5952537,44.94118232,180.9492415,350.2483583,53.12879903,224.3962372,1261.189978,592.7581854,321.6060907,0,0,1979700,3492800,16097387,14921105,6750175,1516092,19146416,2291666,128731,4291366,7597579,14844.894,0.999468321,354.9312977,-2987.329874,5458.227739,8168.026172,8420
19
+ 6/26/2022,Previous Year,252106,392368,225661.2902,50217.3069,35075.3218,90872.7627,159377.57,50460.16773,225119.7108,898742.7005,217408.0645,124521.12,0,783.8586228,851.2196504,300.3451176,203.3583296,28.70458021,125.5195234,336.6139827,78.56584301,215.605161,1234.200295,562.5795688,309.0877084,0,0,2014100,15174300,12563000,7346118,5448531,1101697,17655107,2913059,118494,4387194,10462524,14855.47856,0.941203005,334.4784291,-2814.885723,5143.698096,7692.949185,7665
20
+ 7/3/2022,Previous Year,125454,266419,290633.8637,59997.6562,31465.3904,66524.1613,137024.4399,63677.45909,233819.3122,1001002.206,208138.2258,158374.64,0,623.6384606,840.8641099,324.3629383,202.3052943,240.2171456,95.76678262,334.8709197,127.4832436,214.5120877,1204.274958,541.8456282,307.4871828,0,0,1427200,11198200,15392872,4110014,15478974,866549,13947558,3895914,125234,4284671,13314586,14866.06357,0.943644402,325.9748679,-2813.121521,5160.714951,7731.197049,8186
21
+ 7/10/2022,Previous Year,198588,446493,292359.4341,79576.2833,21440.5073,84024.8804,129785.37,63578.87855,217902.3643,1086562.03,208138.2258,141570.51,0,570.9534282,810.5012067,310.9911019,190.8623186,400.769678,57.01233229,315.9296467,108.8375367,202.3840169,1278.989752,511.1972638,290.0948136,0,0,2344600,16946400,15260991,10091951,19144748,565447,11406040,3528772,125047,4960609,12164302,14876.64903,0.932747126,322.4399174,-2791.632639,5104.750908,7684.081282,7990
22
+ 7/17/2022,Previous Year,190611,445217,237345.855,144865.0243,33749.8102,116644.3072,147560.5811,67523.32011,247165.6411,1084982.767,208138.2258,169180.44,0,565.9144673,868.0299469,301.9873788,202.0068077,507.6894432,157.6772267,334.3768422,135.0554174,214.2630912,1330.862763,541.0461746,307.033508,0,0,2140600,17848700,12913346,13368850,20418110,1404845,16465923,3972606,146277,4856084,14293917,14887.23495,1.009244739,349.1325185,-3025.462028,5527.33841,8316.951968,8312
23
+ 7/24/2022,Previous Year,437548,303678,208039.7865,115988.3537,44791.4311,163478.4265,198315.7998,68275.19077,212064.9762,1065254.809,208138.2258,249588.75,0,776.477908,825.4595302,271.5249881,194.6964057,619.1057667,260.0666358,322.2761157,125.3193069,206.5089226,1452.799799,521.4663146,295.9223064,0,0,4940300,12283700,11942790,14755124,22866566,2290963,19018044,3822078,138760,5690101,20404536,14897.82132,1.05259743,364.3886414,-3149.664995,5768.867771,8855.215417,8015
24
+ 7/31/2022,Previous Year,154795,420078,265189.7712,114836.7368,35355.1122,362539.29,242636.5502,56786.78021,221764.0835,1127712.319,209341.129,216361.61,0,785.3267172,962.6372069,345.4081407,224.2156499,238.5261414,274.3828509,371.1385861,101.5508396,237.8202057,1251.893504,603.1063041,340.7890968,0,0,1922000,17794500,14707130,23043177,12524776,2082698,21709012,3019110,139697,3965118,17906353,14908.40814,1.067497748,369.8094505,-3208.220217,5854.688041,8753.072517,8604
25
+ 8/7/2022,Previous Year,423824,475172,345090.6395,95883.6191,27184.1032,358418.2456,259592.2923,53622.6702,236615.7215,1125131.869,209541.6129,208779.99,0,986.8501755,1025.938955,422.6665647,235.7866071,209.0412688,410.6777854,390.2917036,119.4059165,250.1011998,1417.025462,634.6816576,358.3759871,0,0,5222700,20566800,18421429,27392010,12456497,2921763,23362654,3338402,148393,4334808,17303353,14918.99541,1.160637187,414.2230141,-3486.279245,6370.031497,9758.81855,9350
26
+ 8/14/2022,Previous Year,196578,446369,333412.6969,74145.0094,47811.6696,257428.6672,279454.4899,55740.40666,215816.3565,1270408.936,209541.6129,193941.3,83333,1006.21652,1142.638552,486.4307695,261.8529063,192.5468754,340.7100759,433.4386,135.4558489,277.7534112,1605.035096,704.8459564,397.9945889,103.920732,732319,2107800,19372300,18420426,21392675,11456330,2189064,23226196,3360070,152104,4440820,16103048,14929.58313,1.244984961,444.6414539,-3737.401335,6837.814341,10633.89439,10511
27
+ 8/21/2022,Previous Year,539481,472950,279197.2816,64420.5463,51081.067,220088.3582,212361.9807,55373.48883,225794.8926,1221543.8,209541.6129,156146.6,116667,1045.876273,1071.63155,428.4331739,246.2402262,154.138197,297.8833874,407.5953191,106.1105392,261.1953233,1440.538398,662.8203223,374.2646167,109.3511473,1025246,5287400,17775300,15936937,13459698,10682186,2061564,17073170,2980261,161894,4194978,13072005,14940.17131,1.184962423,423.5047818,-3568.959161,6512.768987,9973.393081,10309
28
+ 8/28/2022,Previous Year,242165,598629,276510.9944,51758.48306,43006.26961,193857.4064,249060.5117,59016.99991,204271.2204,1193881.168,207559.5645,205875.97,116667,924.8436782,982.0672117,380.9582995,222.7309308,62.13676538,205.2154934,368.6809675,108.0664987,236.2580181,2029.075506,595.3198181,338.5324475,109.4662867,1490033,3058100,23797900,16008955,15488743,7128385,1593615,21766973,3257468,156106,7439654,16494119,14950.75993,1.154902931,413.0540781,-3465.403539,6352.05529,9863.05775,9678
29
+ 9/4/2022,Previous Year,372052,618868,299288.3271,74071.86527,46235.88126,319290.8666,233261.2418,64924.9106,208347.5524,1221879.85,204916.8333,228247.73,83333,904.0255621,940.8469486,375.9460785,211.9111493,622.9329915,322.1537139,350.7712524,114.4929439,224.7751952,1238.898241,561.0313292,322.0872816,96.31021073,1050642,4705500,24462400,17288562,29211753,23564611,2581407,17417280,3468022,137686,4191649,17543147,14961.27617,1.11780654,388.6109648,-3360.097385,6152.346742,9467.04322,9390
30
+ 9/11/2022,Previous Year,141091,502019,275061.8104,85805.07331,39866.39394,309816.7901,212855.319,68938.27,198387.2156,1415168.32,204916.8333,264163.23,0,774.0487128,958.7032872,367.374283,216.6169201,911.1160082,304.1690603,358.5605977,102.2195552,229.7675513,1270.879978,573.489781,329.2396609,44.65132361,0,851300,21108600,15586464,27896392,26313039,2365975,15624988,3148953,145661,4209624,19877001,14971.79285,1.141294017,397.0554069,-3440.045218,6286.036062,9683.88297,9883
31
+ 9/18/2022,Previous Year,287300,534750,326380.9092,79077.22839,43472.59557,260566.603,221443.9518,72134.82488,211850.2129,1306922.71,204916.8333,244064.94,0,764.4287881,975.7007039,410.3422984,220.4645506,714.4632252,582.8133759,364.9294848,94.58256909,233.8420917,1181.854654,583.6763205,335.0877386,18.13472182,0,2613500,21910000,18964474,22480219,22380750,4345680,15668026,2992900,136973,3776676,18259281,14982.30998,1.146014298,398.9776597,-3446.770074,6316.468466,9748.996574,10074
32
+ 9/25/2022,Previous Year,486719,603749,227922.4691,74504.97102,36708.70729,291024.5134,198064.0107,64423.84954,224907.174,1138870.73,215293,179372.5,0,923.7236418,960.6266038,331.1681887,217.0223981,717.9420235,414.3210787,359.2317754,77.51748351,230.1648921,1084.965103,596.039424,329.8559537,6.750685498,0,5998100,22001100,12272216,23430698,23019884,3122229,16008431,2688457,126301,3477354,13532554,14992.82755,1.114108771,388.1422359,-3347.635489,6144.925997,9434.761996,9410
33
+ 10/2/2022,Previous Year,368542,550043,206883.4871,66895.83969,56586.04302,229585.0945,146786.561,62470.73401,209080.1229,980464.23,277550,188209.31,0,882.1976889,905.1478389,277.5831914,205.8992085,219.2100648,653.009739,340.8198365,79.39525999,218.36179,1299.117345,682.3431097,312.9496328,2.372080109,0,4433200,18717100,11090274,30235437,12475555,5157988,10009829,2853754,128881,4601977,14481376,15003.33062,1.083001978,388.7004938,-3271.784651,5977.539404,9172.862033,9827
34
+ 10/9/2022,Previous Year,473049,554446,193456.6314,47319.52304,28866.56016,251576.2188,135834.0353,63309.2319,200458.3518,982627.43,277550,191943.9,0,925.6915886,937.4895649,271.0318506,214.0389525,175.4585553,278.0199444,354.2933522,75.45880964,227.0165089,988.3326224,709.3179502,325.3213651,0.906191227,0,6358700,18769000,10636563,33514322,11967380,2118809,8802246,2687855,138005,3169593,14597108,15013.83413,1.005811167,361.248647,-3024.474477,5555.377615,8374.529041,8754
35
+ 10/16/2022,Previous Year,320271,257588,172390.7065,40842.71459,24939.8205,279209.975,303321.9859,70485.89044,194483.3029,907562.39,277550,170900.39,0,959.015952,941.7629421,258.9467906,221.7055116,177.3128816,249.2487123,366.9836166,82.21692268,235.1651607,921.5401156,734.7246713,336.9738958,0.343961469,0,5199900,9291100,9550088,37089009,12010387,1922424,29511029,2788719,150439,2809013,13113052,15024.33808,1.015058292,364.8249183,-3061.922339,5610.374464,8399.218179,9176
36
+ 10/23/2022,Previous Year,309462,473858,143742.1711,44767.07423,24039.58991,306601.5767,260027.3808,73948.70782,196610.4882,970620.47,277550,153744.04,0,930.856466,920.413168,222.6284273,215.216801,146.6142957,236.4479192,356.2430154,101.3337553,228.2855523,1082.155704,713.2213007,327.1115966,0.122224575,0,4887500,16367400,8086323,29973128,11091918,1888981,22977537,3224495,152590,3500989,11708404,15029.51373,1.003615439,360.8364704,-3015.413162,5549.039054,8375.112587,8736
37
+ 10/30/2022,Previous Year,106804,272989,243224.9537,71019.13898,48059.46925,240702.3921,164064.7972,59943.8085,197147.0082,967825.93,223460,238420.23,0,875.7574588,870.6189769,283.5774898,208.1475282,100.8371491,298.5716442,344.541424,79.49592653,220.7864015,960.6661455,587.678263,316.3668912,0.043254893,0,1628300,9768900,13327403,22506463,9424645,2434784,12181101,2782294,148163,3167826,18880255,15034.68949,0.945298511,339.9864429,-2841.140898,5228.401794,7874.335892,7943
38
+ 11/6/2022,Previous Year,263964,89375,229038.8085,76514.37224,63647.98905,215903.2487,141012.1714,52873.49349,177247.5893,1275140.16,201824,245344.69,0,803.6846058,783.0789848,281.3661876,197.9310933,176.2377577,304.2184505,327.6304136,68.92122227,209.9334426,1108.999284,518.1268808,300.8387619,0.015048678,0,2811800,3584700,12937220,23273952,13001073,2583779,10532549,2669429,128973,3981787,19711230,15039.86535,0.931219993,335.0382586,-2818.887044,5152.307302,7749.44065,8409
39
+ 11/13/2022,Previous Year,86304,214207,212803.3877,77271.11333,78911.65973,216805.3193,173711.3487,52649.99309,190824.2938,1390504.61,201824,227619.23,0,647.9625567,770.970499,272.4051279,196.0453894,157.6398366,397.0884418,324.5090549,61.72397847,207.9374168,1290.391574,513.1906484,297.9726492,0.005453042,0,1327000,7440000,12185749,30921410,11984544,3359176,12998845,2527941,138488,4850462,18331246,15037.01057,0.936196087,336.7646439,-2827.22084,5178.856113,7826.242544,9242
40
+ 11/20/2022,Previous Year,22100,123202,179703.9243,55542.65047,86012.6601,198405.0539,170296.5395,56911.87009,156984.4242,604116,201824,190041.78,0,410.51923,875.5737551,287.1069279,230.3808944,45.10005665,312.228454,381.3437619,51.98679658,244.3474116,792.170016,603.0711608,350.1597544,0.002344328,0,360200,4511000,10166399,43713127,5736479,2263309,12483698,2090391,133005,2269792,15327500,15034.15583,0.863292627,310.4811525,-2598.551947,4774.661605,7070.581374,6060
41
+ 11/27/2022,Previous Year,155419,213640,277583.127,86348.15441,72447.91536,181049.6328,150616.1251,50150.7421,194506.1264,699177.1,178803.1613,165553.24,0,515.4365373,871.8631846,348.7779578,224.0776323,67.21391461,251.8782636,370.910129,50.54907139,237.6791529,743.5466564,535.9685021,340.5793215,0.000834175,0,2511300,8305400,15587906,32226910,7959446,1919475,9274360,2139012,147503,2182024,12970833,15031.30111,0.85776999,308.4363716,-2591.07936,4743.216421,7019.05459,8053
42
+ 12/4/2022,Previous Year,335028,159169,264264.8127,74534.29589,64325.55265,207964.8385,126173.5555,41401.0578,144659.3332,303532.25,148108.7097,383055.5,0,775.9431065,751.9638968,317.0579992,199.2553527,76.69204679,291.5840329,329.8224272,34.05423057,211.3571157,873.0841132,413.9884868,302.8515258,0.000271365,0,5057800,4524200,14832172,25547326,8810688,2480180,6922796,1824896,168000,2983668,25019123,15024.97025,0.836356516,292.0013302,-2509.416296,4622.858321,6983.097961,6157
43
+ 12/11/2022,Previous Year,217024,221459,266674.9603,91132.31969,77211.58745,243013.9127,149861.1193,46726.02722,127071.6756,509912.8881,148108.7097,415451.98,0,709.4923926,717.6125648,297.7512423,186.0748608,149.878576,285.1416859,308.0050869,27.63572864,197.3693186,1228.057409,386.6036669,282.8182768,9.27E-05,0,2909800,7725800,14822977,28022013,12497332,2575039,8778666,1717937,134204,4866776,26454507,15018.63955,0.86013449,300.1765219,-2577.895827,4752.284968,7251.006566,6701
44
+ 12/18/2022,Previous Year,170189,180625,238256.6824,83761.11093,67300.2068,185438.328,130245.5708,50974.42721,187761.2745,1059968.868,148108.7097,168145.59,0,756.3419366,722.0103794,287.4807103,189.5386168,134.5352621,220.7993168,313.738556,38.40880097,200.852912,1514.734677,393.8002369,288.0828972,3.45E-05,0,3675600,5708700,13402674,20827912,11320016,1977721,9567174,2060593,101440,6225756,12414622,15012.30901,0.916393615,319.6754713,-2750.47918,5060.985208,7690.505836,8024
45
+ 12/25/2022,Previous Year,314602,607726,285100.341,127608.0109,95029.74951,222804.4207,167050.0305,56748.13002,210500.6445,1281467.545,148108.7097,161907.13,0,921.0774008,925.2288971,355.9887642,218.1475832,301.3272623,337.3294677,361.0942662,84.56738121,230.6153342,1892.842275,453.2404604,331.5661412,1.45E-05,0,4679300,22405900,15698577,24947270,15877592,2611607,16491974,2947421,97318,6955324,12138180,15005.97863,1.139468189,397.3253669,-3450.886871,6290.309971,9649.773715,9809
46
+ 1/1/2023,Previous Year,545467,808537,290565.3025,133285.5116,65702.88461,240465.2635,268375.3215,57117.94715,226317.558,1274962.681,304437.9032,172390,28571,941.8367772,960.9193838,366.8490383,217.6573364,593.495164,303.9119076,360.2827729,134.6944234,230.8385562,2236.397692,772.0546998,330.821007,70.35472737,373333,8981600,28494500,16091871,35440487,21714248,2352010,37241769,3847377,145005,8842329,12882174,14998.29142,1.249734827,422.7333059,-3772.497638,6895.49072,11065.83987,10634
47
+ 1/8/2023,Previous Year,788793,890099,323011.8558,121850.8641,57917.65398,237165.4063,276957.3756,58699.36926,254477.1378,1075025.006,304437.9032,164956.73,50000,954.6035992,988.370554,396.9060203,220.6044148,459.1720798,336.3753656,365.1609984,121.7401462,234.0029461,1867.924583,782.5083143,335.3003204,85.80654375,653333,9374100,29365600,17865302,34729695,18210198,2565984,36542599,3455866,175940,6727543,12333925,14990.60444,1.217366554,411.5734166,-3664.442604,6713.454168,10609.06087,10034
48
+ 1/15/2023,Previous Year,379559,822693,301762.9148,131903.2373,58506.35589,234550.6564,278535.8786,60383.3426,236543.9959,1366871.145,304437.9032,154344.91,50000,996.848517,1036.093236,409.8730378,230.3670254,384.7798026,396.3042818,381.3208049,128.4545641,244.3589615,1781.92823,817.1373766,350.1386748,94.62078669,768047,6008700,27810500,16942041,24834353,16525644,2873246,33108748,3510921,169571,5963442,11588746,14982.9177,1.237397842,418.1311799,-3723.629684,6820.42231,10767.1491,10247
49
+ 1/22/2023,Previous Year,720652,799367,268153.9058,137767.2062,87090.50526,202627.265,274352.0828,61096.04861,234069.5223,1174416.637,304437.9032,143388.69,50000,907.6599112,944.9691158,346.3453952,209.7559482,250.1273413,513.5127134,347.2038016,130.5022088,222.4961142,1511.331964,744.0276007,318.8115555,84.09824673,690750,9560800,27694700,14785079,21179589,14080484,4021248,33601310,3781697,170324,5438931,10705903,14974.20339,1.145810581,386.9575833,-3449.125493,6311.928554,9780.602561,10348
50
+ 1/29/2023,Previous Year,356164,708629,281760.7163,139800.6279,69389.27494,149402.8004,237131.7945,55572.08093,225564.3565,838314.7556,260612.6728,134783.57,21429,774.3921141,800.7599363,284.0726168,178.9583884,259.7907908,402.1916991,296.2253672,89.92870532,189.8279431,1356.106132,566.1600024,272.0018314,57.09380571,296036,5151000,22690500,14327594,14678423,15890321,3669004,24530196,3243694,167624,5805263,9797164,14965.48939,0.986333257,332.9058338,-2964.506395,5430.253673,8326.162444,8648
51
+ 2/5/2023,Previous Year,423082,597173,298207.8085,136646.6205,81488.42809,101442.861,214135.6626,49577.78992,222250.5718,578287.7238,227743.75,147893.43,0,738.2279086,756.6310299,273.7329359,170.6042753,249.3785662,381.535779,282.3970118,63.15497073,180.9661297,1281.839882,488.5086031,259.3042766,22.92877821,0,3729700,19937600,14913449,13333961,15774812,3660862,16501215,2713933,158958,5741290,10976596,14956.77569,0.912465296,326.4769307,-2742.609764,5020.648929,7753.726243,7511
52
+ 2/12/2023,Previous Year,216730,594911,273095.8251,124484.428,70633.65603,69035.8661,189952.8795,39294.37004,195753.1551,509278.6893,227743.75,134976.38,0,806.3032314,823.2695123,290.3194022,186.5988167,193.7645359,354.3389573,308.8723781,46.00288315,197.9323395,1141.09809,534.3074029,283.6146461,9.694651036,0,3053900,19874900,14023180,10484626,13228806,3124964,13568082,2173984,167544,4428126,10527444,14946.60014,0.940151383,336.1540659,-2827.900642,5169.466483,7853.836754,7013
53
+ 2/19/2023,Previous Year,212883,584922,253093.3238,129451.8411,66690.09753,58358.6786,189450.5462,36667.64991,225378.2318,710699.3884,227743.75,216005.84,0,811.9837253,847.926579,288.9377253,192.5718806,148.356776,327.361602,318.7594422,42.54824661,204.2684901,1112.283767,551.4106852,292.6932053,3.736745996,0,2198000,20243800,13342119,10188525,11612210,2823089,14910612,2101636,190210,4130568,18158526,14936.42502,0.941037241,336.2417492,-2824.942234,5170.814899,7824.953286,7991
54
+ 2/26/2023,Current Year,341220,463728,213449.5741,138964.5371,64361.45094,67791.1932,165484.1008,40084.97,233783.7206,1176966.022,219065.7546,125381.99,0,841.0340117,874.3566114,268.0186306,200.5740943,215.6890987,365.3412053,332.0053074,45.39907457,212.7567766,1219.472684,558.0137595,304.8559031,1.434771732,0,3573800,16488200,11024128,12091252,13974495,3026559,14215914,2145907,213687,4396776,10402716,14926.2503,0.990105225,353.5332251,-2954.686989,5436.727808,8274.525974,8430
55
+ 3/5/2023,Current Year,394743,481789,201139.4851,116083.3777,58082.01987,77712.6312,150549.6652,41401.14996,244158.7119,1016509.864,212557.2581,96669.75,0,855.428122,865.155276,254.0903056,200.9145857,157.8896583,371.8603531,332.5689143,47.57359868,213.1179496,1204.589183,546.5852641,305.3733122,0.527259313,0,4389500,14264400,10662771,11809643,11703531,3067687,16115222,2198951,211601,4322257,8139195,14913.31587,0.982079611,340.3303463,-2926.732845,5387.985638,8157.256921,7697
56
+ 3/12/2023,Current Year,200704,477430,195184.287,120896.7912,58215.36271,76736.4059,149648.1686,40789.51997,248001.405,1271798.284,212557.2581,89585.68,0,787.9587837,836.3060115,234.3598207,195.2757268,157.6073414,373.3335881,323.2350515,40.47258073,207.136592,1284.306192,531.244829,296.8017638,0.187669152,0,2339900,14763600,10017585,11756360,12094801,3163516,12652893,2031151,252787,4845654,7554779,14900.38211,0.964426056,333.9228243,-2873.848717,5286.544092,8014.84415,7823
57
+ 3/19/2023,Current Year,113370,397199,181578.8859,124640.5274,57268.67813,74198.894,165109.1346,39110.09,244701.5945,1101826.189,212557.2581,75764.34,0,709.4342034,817.521727,217.9477557,192.0499114,169.4410563,356.1987464,317.8954395,43.24769286,203.7148436,1242.126802,522.4690441,291.877999,0.067547188,0,2243200,13878100,9347447,10708748,12629078,3069645,11221429,2147817,464528,4745567,6412793,14887.44902,0.930742249,321.9804327,-2766.446025,5097.476514,7737.00369,8353
58
+ 3/26/2023,Current Year,372286,280279,95899.13658,145718.6122,47489.00342,63811.6832,157313.7506,39199.93,190371.1529,904118.0758,210064.4355,87952.58,0,688.4936049,766.7113114,167.9836758,184.2114826,194.3286576,292.2202432,304.9206833,44.33831994,195.4003159,1087.191512,496.772508,279.9806566,0.023705804,0,3064700,9385600,6586289,7495720,13747207,2643188,11424885,2220422,830484,4240103,7074442,14874.51661,0.863490894,298.4560502,-2582.208179,4725.047089,7143.871637,7658
59
+ 4/2/2023,Current Year,296533,287966,839440.7583,80005.6611,44952.21867,61913.7068,133744.3853,27249.59999,211036.8524,851730.8103,195107.5,89204.64,0,648.4127851,709.374272,379.7574522,172.9962403,123.0072906,296.386829,286.3563718,25.01102175,183.5038702,1109.919508,441.5925556,262.9361771,0.008144821,0,3021400,9266600,29004913,9540584,11131812,2859054,12123319,1649580,1051857,4698306,7156524,14854.4908,0.8460166,283.4284616,-2533.482223,4623.194575,7012.403333,6573
60
+ 4/9/2023,Current Year,496985,345755,776895.6446,107510.5359,50540.70229,74649.5493,144750.729,27417.49006,208302.3656,868231.3837,195107.5,76853.05,0,636.8844453,636.0402807,370.8363713,154.8687069,375.6187651,277.765361,256.3503169,19.63808085,164.2752875,977.430835,395.3199674,235.3690974,0.002667482,0,4367200,10965300,27656240,7165015,20965368,2981370,11445606,1589926,1226521,4603663,6439068,14834.46661,0.790599655,264.5058986,-2359.974708,4314.535769,6719.467142,6964
61
+ 4/16/2023,Current Year,272813,371375,737931.7459,125896.9064,50640.63176,75339.1312,162123.8022,28594.20994,200339.7171,832255.7285,195107.5,67629.3,0,643.202747,697.9311949,400.1671801,169.0921007,303.9842128,288.5176945,279.8939469,26.0160255,179.362597,999.7052811,431.6267961,256.9079406,0.001065489,0,2297300,11734600,25705317,5737111,16996289,2838151,12923759,1783221,1454854,4249133,5795966,14814.44404,0.845903975,282.6267271,-2515.728637,4610.116938,7053.42381,7222
62
+ 4/23/2023,Current Year,306667,365603,723662.1242,164670.3036,52682.734,74732.6563,156280.0437,28179.85997,182218.3614,843651.3365,195107.5,56866.86,0,680.2328465,768.0223303,428.1466005,185.2406354,369.5169101,285.729516,306.6242236,25.94739503,196.4919844,1082.094568,472.8477793,280.8264039,0.00042702,0,2706900,12139000,24584150,5514045,18276249,2579772,9879046,1673868,1817220,4187517,4914688,14787.83098,0.938684752,313.0624987,-2784.602695,5106.575527,7716.75695,7780
63
+ 4/30/2023,Current Year,396982,476592,1278930.594,94028.52121,58683.5318,79745.2575,173283.6224,27399.14003,184983.4865,963638.67,211661.2097,89565.85,10526,757.8051683,805.1918653,568.5505022,191.6262435,177.0239561,342.9543489,317.194154,25.48726963,203.2654434,1077.23059,519.6833732,291.2532891,76.08094879,733333,3777900,14567800,43614120,6941908,12143455,2983264,13874403,1635899,2736075,3997660,7520502,14761.2208,0.987383803,328.7116385,-2916.982804,5361.8393,8126.915288,8299
64
+ 5/7/2023,Current Year,570046,375182,1454493.2,86361.22922,61354.77971,80520.5706,181210.1102,26662.37002,204030.178,955481.1717,214420.1613,90065.85,5263,816.8896164,809.7824501,623.0873893,193.3403495,132.8104708,432.388876,320.0314696,25.5940547,205.0836617,1114.644548,529.3989259,293.8598601,65.16989915,366667,4796000,12391600,48413175,10798149,11036269,3682307,14679833,1636754,2657555,4121268,7561405,14734.6135,1.017371579,368.8924686,-3020.799168,5514.725091,8424.899963,8512
65
+ 5/14/2023,Current Year,296089,448559,1294476.154,91769.75635,53823.65675,78061.8633,184795.8188,28415.27009,199934.8729,1010715.693,214420.1613,79717.77,10526,846.3276207,871.5314255,650.3059216,206.9104899,120.1442642,284.4808969,342.4937854,26.57100509,219.4780398,1124.917313,566.5562901,314.4755735,42.71769839,62179,2853300,14068200,42327534,7500243,10327294,2285168,14316686,1609950,2794939,3840627,6734988,14704.66761,1.0398098,376.2621712,-3076.705922,5624.897804,8541.364376,9243
66
+ 5/21/2023,Current Year,160204,425598,767934.9728,85217.3743,50954.82908,76221.5531,184514.1419,29728.33993,180459.1612,958720.1041,214420.1613,64173.93,12281,742.3856418,860.1913668,534.25428,204.0773489,76.52708573,250.7751673,337.8041576,33.16461757,216.4728164,1153.774175,558.7986658,309.9620644,39.4479893,72542,1935200,13575600,25753701,6864734,8360015,2089089,14230194,1836640,3238776,4025155,5477028,14674.72539,0.9947362,359.2190374,-2933.818775,5370.112994,8113.148633,8916
67
+ 5/28/2023,Current Year,250675,164333,419541.4469,92407.1617,51779.85515,82406.486,134034.1601,25999.13002,202719.13,865316.4701,212327.0065,77708.92,12281,685.9715645,854.9860127,419.3190634,211.2394701,56.89628875,237.4167674,349.6594386,30.06195147,224.0699582,1257.584361,574.2115765,320.9980289,40.58729967,72542,2089800,5739600,15776548,7959335,7278021,1925256,12149790,1682843,3187686,4285196,6147304,14644.78684,0.997152597,359.3570075,-2940.158384,5372.175565,8054.37597,7633
68
+ 6/4/2023,Current Year,454552,326557,178039.9105,107296.305,59912.29332,98009.998,124015.4385,24058.83999,200243.0556,962751.9041,209536.1333,91046.7,12281,659.741062,815.6101963,262.1682047,200.0668991,127.797631,483.0461649,331.1657597,27.1864638,212.2187756,1081.350495,538.5222072,304.0791733,38.42146311,72542,2694900,10771300,8239580,7557997,11324623,3996079,12577989,1653862,3326217,3813829,7118757,14614.85196,0.961935917,336.3091816,-2826.149411,5171.851894,7763.38616,7946
69
+ 6/11/2023,Current Year,235510,286902,171561.497,105889.0964,58265.83951,97295.2469,125657.1791,25259.50999,211165.5855,995018.0656,209536.1333,85579.09,12281,626.4784725,774.5792218,209.65455,191.0967281,148.6190586,460.9364201,316.317659,28.18699555,202.7037649,1048.60873,514.3771024,290.4383861,36.6973037,72542,2600200,9299000,8371940,6809829,12005995,3931641,11667680,1735507,3042625,3883400,6694737,14584.10993,0.917206666,319.9965487,-2693.298925,4920.991893,7396.38391,8152
70
+ 6/18/2023,Current Year,331154,256804,154548.52,105000.3055,59451.7022,122955.4783,129291.6488,26009.03002,212768.8285,516324.339,209536.1333,74601.59,12281,638.0935884,776.2166825,193.4182543,192.1920365,148.6214006,430.1358818,318.1306957,23.94794524,203.8656012,867.7902211,517.3253556,292.0209331,36.90751782,72542,2701300,9215400,7982337,10147869,11844421,3655848,11208838,1572458,2855496,3088540,5848506,14553.37179,0.883522009,307.5949207,-2591.719553,4730.276365,7084.817847,6498
71
+ 6/25/2023,Current Year,332565,374344,141291.5239,97507.33251,53337.63933,105482.1308,125471.5367,27457.16003,212608.884,465680.9,212993.271,69105.64,12281,615.7519552,779.0937361,175.7288582,188.932373,174.7887979,341.5503578,312.7350559,24.54955316,200.4079488,836.245072,514.770607,286.9062403,36.28153974,72542,2537900,12921200,7312379,8962022,12962164,2979552,11741360,1626270,2973297,3018460,5447063,14522.63756,0.854375384,296.8194723,-2504.700729,4564.568659,6844.429498,6777
72
+ 7/2/2023,Current Year,239886,117700,151342.3838,123982.921,62908.77255,89027.2117,150623.9129,31640.63004,260611.6412,890020.45,233736.0968,78034.31,12281,621.2794795,764.9240996,174.1094132,194.5021389,325.8319993,471.0434465,321.9545507,36.67334949,206.3160171,785.0143666,567.758123,295.5412035,37.35112627,72542,2492700,4338000,7136684,9500121,17279683,3975386,18997320,1992729,3270678,2716598,6016457,14491.89307,0.924319545,311.2626577,-2699.369673,4927.796617,7341.988916,7036
73
+ 7/9/2023,Current Year,233296,291544,137307.2144,129684.7264,65007.1195,122212.761,155694.5852,30720.50003,224941.8929,746005.43,233736.0968,73925.31,12281,580.9318638,760.7512215,160.1609936,189.3726234,286.0264842,556.4721175,313.4637914,34.28548491,200.8749396,985.469408,552.7848992,287.6860648,36.36608213,72542,2348500,10446600,6628072,10942180,15905482,4764977,17261652,1908516,2943395,3645774,5716712,14461.15249,0.943914972,317.1871208,-2746.917392,5021.590551,7536.506255,7867
74
+ 7/16/2023,Current Year,327243,545238,177351.2321,128088.4128,63976.58201,116834.971,155627.4038,29017.24002,242860.592,925505.06,233736.0968,68290.1,12281,691.0363912,729.0096528,172.3823025,170.2445186,337.2839681,652.624446,281.8015154,25.51385772,180.5850116,1625.024876,496.9493337,258.4400254,32.69282556,72542,4979700,22191300,8988687,10189838,18380941,6161481,14616864,1720073,3220450,7945935,5305212,14430.41584,1.022518206,342.8701363,-2960.996268,5428.194665,8463.657257,8453
75
+ 7/23/2023,Current Year,194380,649399,220726.0862,128009.0114,56922.01315,98030.1415,143218.28,32128.63005,214693.243,1146626.68,233736.0968,58344.8,12281,687.8649333,893.0019017,244.0713041,203.3442754,372.0055376,527.8809181,336.5907193,34.34863145,215.6952167,1592.53979,593.5686097,307.4307526,39.0491217,72542,1480600,24728600,11001615,8082706,17379525,4156896,12288014,1860820,2750558,6061528,4571527,14399.68312,1.112294375,372.1794934,-3204.38233,5892.209692,9107.398568,9452
76
+ 7/30/2023,Current Year,86108,544290,290185.1936,123863.353,58330.93184,86410.0764,155115.7987,28852.43002,248878.2461,1272961.2,240644.6452,109460.83,12281,543.4952059,925.5413754,306.0685377,210.6151761,546.8054746,544.1495942,348.6260603,31.05021476,223.4077451,1544.034657,628.1932532,320.1174898,40.44538568,72542,1371200,20416500,14101250,7582452,20910951,4194963,12986633,1712141,3738131,5561447,9321195,14368.95434,1.14774298,383.221242,-3321.137123,6067.018621,9341.65291,9954
77
+ 8/6/2023,Current Year,245045,452277,271285.4598,148609.0874,59087.93692,101211.9591,186547.648,31401.73997,271102.2596,1333948.57,243408.0645,146602.84,12281,621.9390612,969.2205314,326.5280836,221.6818558,519.0192833,226.46071,366.9444598,35.7977093,235.1466046,1757.373196,666.8102041,336.937941,42.57057027,72542,2544300,18107700,13359708,9695495,19435726,1694161,17021723,1816464,3806588,6159534,12515514,14338.22951,1.168079726,423.6580756,-3389.998312,6161.31669,9521.406664,10016
78
+ 8/13/2023,Current Year,207775,525640,247636.6711,172321.5628,74479.45872,105352.5335,181990.3875,34950.71999,250519.2334,898537.75,243408.0645,149679.68,83709,628.9128166,1014.287182,326.0213373,231.8445167,602.0250578,230.9748621,383.7664595,41.77518663,245.926536,1682.047707,697.3790839,352.3843384,100.8056128,999815,2191800,19453700,12220343,11735461,20644365,1726070,16105663,1921017,3210333,5487324,12862137,14307.50483,1.201178626,434.7293605,-3473.68026,6322.327884,9821.527681,9725
79
+ 8/20/2023,Current Year,104380,476598,137259.8184,164084.5177,59550.18023,100797.403,170978.7014,36535.90003,267734.126,982752.91,243408.0645,129049.38,178947,335.2835947,967.1172924,311.8617942,221.3894094,400.6572593,138.0241161,366.4603804,47.34643425,234.8363952,2270.35583,665.9305368,336.4934467,119.951625,2236178,612400,18724100,12549233,10222874,16973749,1105403,14418235,2102400,3649701,8817137,11365877,14276.78412,1.176570134,424.908763,-3383.817873,6179.505606,9636.304611,10162
80
+ 8/27/2023,Current Year,185234,574493,182869.6013,158305.9904,52232.30568,100303.5994,142034.8715,33586.50998,196927.0233,795223.26,225376.2366,93407.95,168421,516.0096306,1052.901423,291.3082569,239.4361589,385.581239,133.5620316,396.3327159,42.79171664,253.9792874,1760.723528,680.3115125,363.9228016,132.6774217,2353525,2544000,21833200,9652993,8826199,16361491,1011762,12404779,1879061,3585176,5583532,7944429,14246.06738,1.177107661,424.1882706,-3384.192866,6169.027388,9458.560517,8896
81
+ 9/3/2023,Current Year,103700,708432,181724.0366,138161.3067,33449.5896,201395.6946,144748.3585,29073.51997,211116.3949,820223.62,180296.6667,91586.83,95238,425.218926,907.3804626,232.4505875,204.0199436,241.6556935,95.21978422,337.709136,23.15806633,216.4119243,2604.193939,491.0303535,310.0921179,100.0283307,1356047,1892700,26006600,9345022,15331148,14066772,857967,11072389,1471803,3685136,12456063,7541850,14215.35461,1.140271094,410.0277861,-3276.658372,5963.089547,9285.028226,9284
82
+ 9/10/2023,Current Year,307483,693239,223459.8058,134343.7025,41363.28634,235570.0892,146508.4582,28580.83,215075.5843,881303.17,180296.6667,89111.75,0,548.9105155,831.4659197,253.1288112,186.4398897,168.5357607,96.55435719,308.6093103,16.30543897,197.7640744,2650.370027,448.7190973,283.371267,42.36547919,0,3200300,24717900,12854652,16484280,12493907,951076,10929834,1315070,3920655,15094450,7405831,14184.64583,1.097291208,393.7203579,-3127.484723,5725.928413,9024.703996,8727
83
+ 9/17/2023,Current Year,91002,695876,206090.5335,160719.7739,54946.43826,230605.8267,143407.0754,29111.96995,258559.207,851947.42,180296.6667,73603.74,0,446.710714,780.6749097,237.2757502,175.0754168,132.8388084,150.8661646,289.797981,12.31574625,185.709334,2874.469183,421.3673538,266.0610285,16.03044292,0,1818100,23868500,11932621,17632033,11626135,1528679,10829900,1187256,3250200,20279493,6140952,14153.94104,1.079501879,386.4988979,-3074.778894,5620.905744,8921.818581,8551
84
+ 9/24/2023,Current Year,117941.8667,634668,169137.1128,163968.9603,63951.70373,213293.3697,133950.3368,26454.40996,238207.469,791154.93,180296.6667,94783.75,0,560.6133792,920.1635269,244.8992536,209.1039271,131.297661,207.1889954,346.1245273,12.7478761,221.8047042,1705.547661,503.2663639,317.8205296,7.268312037,0,2383140,17189000,9226724,17716838,10678044,1724928,8594796,1113644,2655778,6397273,9468631,14123.24025,1.045465525,373.5008018,-2972.530715,5431.872674,8220.689478,8436
85
+ 10/1/2023,Current Year,144881.7333,546186,148464.7941,106100.0614,44560.94488,68372.2928,119251.0693,18204.23,219321.0186,801167.92,167920.9677,101080.2,0,678.3406906,944.4331704,226.8916795,217.8674745,94.41199605,185.0175423,360.6306093,7.842450148,231.1005413,1791.039282,497.2463016,331.1403988,2.808861543,0,2948180,14539100,8168663,7926608,8952937,1484611,9947675,843052,3432735,6464882,10067723,14092.54347,1.081199244,385.4274055,-3068.460874,5605.322884,8491.060415,7704
86
+ 10/8/2023,Current Year,171821.6,480839,140296.1387,98745.80287,49678.07081,67057.9228,122035.4445,19747.51999,224898.2764,730743.37,167920.9677,101081.84,0,763.9269378,906.1479737,207.8916876,211.168603,92.25577093,191.036741,349.542134,6.773499719,223.9947866,1500.683497,481.9572407,320.9586728,1.001048031,0,3513220,14218000,7900420,7894290,9199792,1583398,7699938,821024,5324362,5343811,10107386,14061.8507,1.033875786,367.7547764,-2930.627633,5348.30745,8042.773187,7576
87
+ 10/15/2023,Current Year,198761.4667,529764,134232.5671,120340.3735,54812.81998,67140.6146,125704.1557,19651.91001,222630.8507,1014913.11,167920.9677,89773.82,115385,814.021625,867.0010643,193.496147,203.0211766,74.29807486,181.8273082,336.0559018,7.487252365,215.3524932,1595.030622,463.3620941,308.5752506,83.28439757,820538,4078260,14480500,7695562,7210303,8414392,1565710,8714810,890240,5982292,6086777,8933762,14031.16196,1.042045786,369.8519517,-2950.709555,5378.806954,8140.762758,8189
88
+ 10/22/2023,Current Year,225701.3333,500130,127323.4546,138155.8029,52204.69878,63869.2728,136008.1581,20213.08004,218489.2155,1057040.099,167920.9677,74650.34,19238,887.494946,890.435337,194.4830652,210.1274647,67.4865255,162.9667114,347.8187636,8.764300735,222.8904105,1777.06454,479.5810155,319.3751355,58.98317443,173513,4643300,13090800,7448790,6179627,7965871,1366486,8276849,943196,5504829,6716537,7510308,14000.47725,1.088299039,385.4238287,-3068.275664,5605.270867,8549.890422,8517
89
+ 10/29/2023,Current Year,252641.2,300262,198209.9991,120650.5446,45480.17169,68876.9377,137625.577,18210.34004,202973.2023,1027683.58,150659.4624,112537.64,0,981.0546288,932.5152103,284.8555313,227.94298,90.0912389,190.2309151,377.3083429,8.880990517,241.7880237,1088.380818,479.6898561,346.4543277,26.44608201,0,5208340,6772000,12039092,6882787,8895774,1470715,12268890,903186,4114121,3295336,10493856,13969.79658,1.057564946,373.7185068,-2979.177696,5435.038787,8105.218543,7620
90
+ 11/5/2023,Current Year,279581.0667,343885,191456.4959,112302.3586,43870.77929,76947.0105,129311.3217,20177.23004,203508.2652,757193.75,137713.3333,159552.57,0,943.6225993,880.2052338,283.417584,218.2384532,73.76391771,189.9813722,361.2446811,8.617717067,231.4940529,773.8454245,429.3467486,331.7042561,9.711508801,0,5773380,8266300,11524213,8886193,8134593,1527561,9417195,913321,1090643,2348733,16083626,13939.11996,0.962892104,330.2892358,-2695.269527,4937.629502,7307.842761,7026
91
+ 11/12/2023,Current Year,306520.9333,240286,198659.6141,110565.2847,43981.93758,74725.7699,134664.8774,22208.30993,204083.8664,739371.35,137713.3333,160279.97,0,859.9426368,784.7082927,268.7375762,198.7428744,52.96298974,155.7534535,328.9741347,8.086477292,210.8143309,843.1577668,390.992539,302.0726015,3.293174362,0,6338420,6622900,12131884,7395280,7288106,1381296,9198296,927326,695308,2875295,16417135,13908.44739,0.884405321,302.6993151,-2467.467308,4525.17644,6768.647295,6804
92
+ 11/19/2023,Current Year,333460.8,265966,199930.4602,106661.5212,44236.74205,71996.427,133195.2935,22524.47001,160690.9638,459898.9,137713.3333,133874.58,0,841.5834198,761.789057,267.9687151,194.4867235,47.90933731,136.5205807,321.929034,6.759498821,206.2996654,655.4502986,382.6192916,295.6036069,1.18667682,0,6903460,7119700,12301550,6730019,7108764,1248480,7476269,850714,544606,2219812,13651130,13877.77889,0.815389075,278.4622261,-2261.826758,4162.846239,6299.587612,4948
93
+ 11/26/2023,Current Year,360400.6667,402368,166378.1433,97338.75092,39050.71145,70561.6492,124345.3145,19662.66999,155469.3708,809034.46,140683.4409,109810.26,0,810.4858422,750.223927,218.9064763,187.2994981,38.94589943,119.5074091,310.0321989,4.790676071,198.6758948,934.3953915,374.4267708,284.6796236,0.419087036,0,7468500,10269500,9096552,6614985,6561769,1144564,7069589,728350,487978,3468738,9915898,13847.11445,0.833041004,283.8618962,-2299.493141,4243.568125,6460.725575,7342
94
+ 12/3/2023,Current Year,387340.5333,347111,179740.9957,85696.62872,35085.92571,77284.3684,126989.0472,15156.67001,119245.4383,786300.05,148108.7097,124380.65,0,794.1794746,739.8412707,197.3078416,183.5311519,59.25797091,138.3346547,303.7945489,4.317132205,194.6786626,999.79707,381.3186586,278.9520513,0.150363814,0,8033540,9800000,8639105,8503376,8227261,1342636,8712259,710018,426827,3849768,10626842,13816.4541,0.844150749,287.0106735,-2331.668609,4290.640491,6521.443408,6918
95
+ 12/10/2023,Current Year,414280.4,384155,164476.7674,81470.93615,35715.93495,77344.6241,132235.4494,15154.94002,186757.1516,885398.08,148108.7097,88387.51,0,799.0346099,751.2994538,185.4197449,184.6531506,39.08780584,133.8354685,305.6517654,4.522006415,195.8688104,932.1781895,383.6498107,280.6566165,0.055362369,0,8598580,10755800,8036611,9447463,6504942,1288360,8307670,728919,494797,3517425,7441930,13785.79783,0.830495813,281.7414799,-2289.071177,4211.869151,6400.452249,6688
96
+ 12/17/2023,Current Year,441220.2667,466503,156063.2897,82342.2783,35694.39084,75300.5488,132636.4486,14869.72996,148728.6407,950712.32,148108.7097,76075.89,0,740.9191363,707.0078691,165.898516,171.2229372,30.97593247,126.4293179,283.4210673,4.152010161,181.6228584,1382.04466,355.7461502,260.2234982,0.018782607,0,9163620,12600400,7832276,9407971,6176622,1312608,9017217,723461,1279339,6308645,6370818,13755.14565,0.86309122,292.1482782,-2375.795357,4367.444654,6693.480311,6242
97
+ 12/24/2023,Current Year,468160.1333,633323,147385.5938,118372.1275,54532.80246,114900.1679,178008.4321,28385.81997,145360.8156,901847.53,148108.7097,69345.22,43478,771.1616752,794.0299265,166.834395,178.2118461,52.33955324,190.8943106,294.9896343,16.1961226,189.0362671,1377.89555,370.2668533,270.7619601,61.54687964,461538,9728660,36254900,7529975,15894797,7906239,1862757,12826455,1439190,826171,5960017,5788554,13724.49758,0.940954538,317.7946158,-2597.978681,4750.842294,7204.823203,6837
98
+ 12/31/2023,Current Year,495100,836571,413828.4161,135607.8276,65070.98728,141086.2212,178054.5782,36279.99004,256528.1386,1434686.96,149553.5484,173432.89,87451,902.4842186,944.0734789,342.6691304,208.5598699,74.90915424,268.009429,345.223963,49.28293154,221.2276015,1673.222589,436.4837233,316.9936163,86.29973693,807692,10293700,34097600,18229752,23112261,8524823,2194786,16295052,2290659,1537472,6257895,13666893,13693.85362,1.146827096,386.4604591,-3177.038883,5777.356201,8856.217219,9905
99
+ 1/7/2024,Current Year,494272,704309,472678.2883,141870.9258,68194.70073,140547.9016,185503.658,39933.35982,268226.6481,1274746.37,149794.3548,172056.07,85103,886.1177399,925.4876581,399.2989247,204.7776534,100.4824572,253.4924168,338.9633542,57.15484452,217.2156567,2438.813385,429.0850088,311.2449625,93.51421135,1131500.02,7151200,27654100,20915152,20386665,9840462,2108080,16739286,2412071,1756869,11104319.5,13829687,13663.21378,1.232141329,414.2808202,-3405.441204,6193.254209,9857.742099,9688
100
+ 1/14/2024,Current Year,688323,766430,423226.4523,145148.5704,67952.72641,181164.4937,188756.9511,39351.34999,241547.6379,1048099.35,149794.3548,147538.76,96467,930.9929903,975.8722935,418.1218049,215.1481133,92.07061249,317.3728997,356.1293184,58.26787291,228.2160087,2356.367813,450.8149622,327.0071971,101.2048688,1240693,10526300,31046400,19239428,24937994,9038994,2493677,14627564,2346392,1408905,9733736.5,12396750,13632.57806,1.261075648,423.0586425,-3472.670608,6324.477482,10102.45227,9496
101
+ 1/21/2024,Current Year,507279,779454,366000.6717,144577.2874,65124.18209,179989.7854,190943.7405,39138.78997,247516.0307,944413.85,149794.3548,168013.15,39772,944.7091262,991.9503913,404.4381143,218.317848,97.06020522,285.3321032,361.3761013,63.32363006,231.5782701,2132.63934,457.45673,331.8249295,80.39592249,459729,8413000,31045300,17539639,22784963,9286778,2211021,16379059,2447307,1885623,8213668.5,14130960,13601.94648,1.24446204,416.5471377,-3423.36186,6227.134321,9820.722309,9481
102
+ 1/28/2024,Current Year,194881,823167,294534.7607,129204.3701,57011.30726,149089.4573,160154.47,28360.51,232525.632,900720.85,154221.7742,188543.43,39772,756.8327128,796.77418,291.755412,174.900493,62.45330919,183.3266773,289.5084339,34.6330342,185.5237855,2403.826128,374.5639516,265.8341692,62.15022457,459729,3065500,32599700,14704172,17821469,8301727,1797650,12971027,1949165,1895113,14183034,15790996,13571.31904,1.115622714,372.5811227,-3060.606795,5569.868297,8763.925136,8464
103
+ 2/4/2024,Current Year,355825,592828,278225.8458,119061.7664,50106.11295,243124.462,153795.669,19181.87011,206332.7615,910664.9,160125,197558.12,0,678.2223822,706.1173784,247.9555963,156.7341714,48.12657472,123.9688776,259.4381739,13.7724102,166.2540585,1910.152171,345.2289379,238.2228749,23.90546722,0,5121700,22724500,14157612,26958625,7799915,1384811,9279106,1260084,1187799,11529083,16475569,13540.69576,0.951731151,334.8636639,-2603.190093,4740.899867,7390.672513,7771
104
+ 2/11/2024,Current Year,136151,461470,270862.9029,134659.3716,46421.62082,272024.6002,182926.9828,21299.35994,205524.9325,586472.64,160125,196341.71,0,698.2864765,717.9268176,249.9909147,161.4955493,45.71740336,113.8285012,267.3195642,13.13273961,171.304638,1352.231509,355.7165388,245.4597723,9.597072979,0,2600200,18945500,13997446,26404327,7556780,1252983,9922448,1284682,802737,6626599,15571859,13510.07663,0.871031325,305.7766697,-2376.944197,4329.094879,6659.934849,6158
105
+ 2/18/2024,Current Year,309094,553468,342945.5078,137580.8666,50187.28304,294154.5019,182645.7417,21379.31,197194.7453,771163.68,160125,200097.88,0,697.868311,716.6343822,263.1942582,161.5547736,41.50723114,112.8980681,267.4175967,12.93070055,171.3674596,1243.833141,355.8469885,245.5497883,3.596622212,0,4286500,21920700,15510901,26927273,7233926,1247092,10196493,1279582,782854,5927051,16302166,13479.46167,0.853142374,298.8180458,-2325.127447,4230.576758,6498.466679,6818
106
+ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,38637.1339,38570
response_curves_model_quality.py ADDED
@@ -0,0 +1,506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ from scipy.optimize import curve_fit
5
+ from sklearn.preprocessing import MinMaxScaler
6
+ import warnings
7
+ warnings.filterwarnings("ignore")
8
+ import plotly.graph_objects as go
9
+ from utilities import (channel_name_formating)
10
+
11
+ ## reading input data
12
+ df= pd.read_csv('response_curves_input_file.csv')
13
+ df.dropna(inplace=True)
14
+ df['Date'] = pd.to_datetime(df['Date'])
15
+ df.reset_index(inplace=True)
16
+
17
+ channel_cols = [
18
+ 'BroadcastTV',
19
+ 'CableTV',
20
+ 'Connected&OTTTV',
21
+ 'DisplayProspecting',
22
+ 'DisplayRetargeting',
23
+ 'Video',
24
+ 'SocialProspecting',
25
+ 'SocialRetargeting',
26
+ 'SearchBrand',
27
+ 'SearchNon-brand',
28
+ 'DigitalPartners',
29
+ 'Audio',
30
+ 'Email']
31
+ spend_cols = [
32
+ 'tv_broadcast_spend',
33
+ 'tv_cable_spend',
34
+ 'stream_video_spend',
35
+ 'disp_prospect_spend',
36
+ 'disp_retarget_spend',
37
+ 'olv_spend',
38
+ 'social_prospect_spend',
39
+ 'social_retarget_spend',
40
+ 'search_brand_spend',
41
+ 'search_nonbrand_spend',
42
+ 'cm_spend',
43
+ 'audio_spend',
44
+ 'email_spend']
45
+ prospect_cols = [
46
+ 'Broadcast TV_Prospects',
47
+ 'Cable TV_Prospects',
48
+ 'Connected & OTT TV_Prospects',
49
+ 'Display Prospecting_Prospects',
50
+ 'Display Retargeting_Prospects',
51
+ 'Video_Prospects',
52
+ 'Social Prospecting_Prospects',
53
+ 'Social Retargeting_Prospects',
54
+ 'Search Brand_Prospects',
55
+ 'Search Non-brand_Prospects',
56
+ 'Digital Partners_Prospects',
57
+ 'Audio_Prospects',
58
+ 'Email_Prospects']
59
+
60
+ def hill_equation(x, Kd, n):
61
+ return x**n / (Kd**n + x**n)
62
+
63
+
64
+ def hill_func(x_data,y_data,x_minmax,y_minmax):
65
+ # Fit the Hill equation to the data
66
+ initial_guess = [1, 1] # Initial guess for Kd and n
67
+ params, covariance = curve_fit(hill_equation, x_data, y_data, p0=initial_guess,maxfev = 1000)
68
+
69
+ # Extract the fitted parameters
70
+ Kd_fit, n_fit = params
71
+
72
+
73
+ # Generate y values using the fitted parameters
74
+ y_fit = hill_equation(x_data, Kd_fit, n_fit)
75
+
76
+ x_data_inv = x_minmax.inverse_transform(np.array(x_data).reshape(-1,1))
77
+ y_data_inv = y_minmax.inverse_transform(np.array(y_data).reshape(-1,1))
78
+ y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
79
+
80
+ # # Plot the original data and the fitted curve
81
+ # plt.scatter(x_data_inv, y_data_inv, label='Actual Data')
82
+ # plt.scatter(x_data_inv, y_fit_inv, label='Fit Data',color='red')
83
+ # # plt.line(x_data_inv, y_fit_inv, label=f'Fitted Hill Equation (Kd={Kd_fit:.2f}, n={n_fit:.2f})', color='red')
84
+ # plt.xlabel('Ligand Concentration')
85
+ # plt.ylabel('Fraction of Binding')
86
+ # plt.title('Fitting Hill Equation to Data')
87
+ # plt.legend()
88
+ # plt.show()
89
+
90
+ return y_fit,y_fit_inv,Kd_fit, n_fit
91
+
92
+ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
93
+ fit_col = 'Fit_Data_'+channel
94
+ plot_df = pd.DataFrame()
95
+
96
+ plot_df[f'{channel}_Spends'] = X
97
+
98
+ plot_df['Date'] = df['Date']
99
+ plot_df['MAT'] = df['MAT']
100
+
101
+
102
+
103
+ y_fit_inv_v2 = []
104
+ for i in range(len(y_fit_inv)):
105
+ y_fit_inv_v2.append(y_fit_inv[i][0])
106
+
107
+ plot_df[fit_col] = y_fit_inv_v2
108
+
109
+ # adding extra data
110
+
111
+ y_fit_inv_v2_ext = []
112
+ for i in range(len(y_fit_inv_ext)):
113
+ y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
114
+
115
+ # # # # print(x_ext_data)
116
+ ext_df = pd.DataFrame()
117
+ ext_df[f'{channel}_Spends'] = x_ext_data
118
+ ext_df[fit_col] = y_fit_inv_v2_ext
119
+
120
+ ext_df['Date'] = [
121
+ np.datetime64('1950-01-01'),
122
+ np.datetime64('1950-06-15'),
123
+ np.datetime64('1950-12-31')
124
+ ]
125
+
126
+ ext_df['MAT'] = ["ext","ext","ext"]
127
+
128
+ # # # # print(ext_df)
129
+ plot_df= plot_df.append(ext_df)
130
+ return plot_df
131
+
132
+ def input_data(df,spend_col,prospect_col):
133
+ X = np.array(df[spend_col].tolist())
134
+ y = np.array(df[prospect_col].tolist())
135
+
136
+ x_minmax = MinMaxScaler()
137
+ x_scaled = x_minmax.fit_transform(df[[spend_col]])
138
+ x_data = []
139
+ for i in range(len(x_scaled)):
140
+ x_data.append(x_scaled[i][0])
141
+
142
+ y_minmax = MinMaxScaler()
143
+ y_scaled = y_minmax.fit_transform(df[[prospect_col]])
144
+ y_data = []
145
+ for i in range(len(y_scaled)):
146
+ y_data.append(y_scaled[i][0])
147
+
148
+ return X,y,x_data,y_data,x_minmax,y_minmax
149
+
150
+ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
151
+ # # # # print(x_max)
152
+ x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
153
+ # x_ext_data = [1500000,2000000,2500000]
154
+ # x_ext_data = [x_max+100,x_max+200,x_max+5000]
155
+ x_scaled = x_minmax.transform(pd.DataFrame(x_ext_data))
156
+ x_data = []
157
+ for i in range(len(x_scaled)):
158
+ x_data.append(x_scaled[i][0])
159
+
160
+ # # # # print(x_data)
161
+ y_fit = hill_equation(x_data, Kd_fit, n_fit)
162
+ y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
163
+
164
+ return x_ext_data,y_fit_inv
165
+
166
+ def fit_data(spend_col,prospect_col,channel):
167
+ ### getting k and n parameters
168
+ temp_df = df[df[spend_col]>0]
169
+ temp_df.reset_index(inplace=True)
170
+
171
+ X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
172
+ y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
173
+ # # # # print('k: ',Kd_fit)
174
+ # # # # print('n: ', n_fit)
175
+
176
+ ##### extend_s_curve
177
+ x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
178
+
179
+ plot_df = data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext)
180
+ return plot_df
181
+
182
+ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
183
+ plotly_data.tail()
184
+
185
+ for i in range(1,13):
186
+ # # # # print(i)
187
+ pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
188
+ plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
189
+
190
+ def response_curves(channel,x_modified,y_modified):
191
+
192
+ # Initialize the Plotly figure
193
+ fig = go.Figure()
194
+
195
+ x_col = (channel+"_Spends").replace('\xa0', '')
196
+ y_col = ("Fit_Data_"+channel).replace('\xa0', '')
197
+
198
+ # fig.add_trace(go.Scatter(
199
+ # x=plotly_data[x_col],
200
+ # y=plotly_data[y_col],
201
+ # mode='markers',
202
+ # name=x_col.replace('_Spends', '')
203
+ # ))
204
+
205
+ fig.add_trace(go.Scatter(
206
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
207
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
208
+ mode='lines+markers',
209
+ name=x_col.replace('_Spends', '')
210
+ ))
211
+
212
+ plotly_data2 = plotly_data.copy()
213
+ plotly_data2 = plotly_data[plotly_data[x_col].isnull()==False]
214
+ # # print(plotly_data[plotly_data2['Date'] == plotly_data2['Date'].max()][x_col])
215
+ # .dropna(subset=[x_col]).reset_index(inplace = True)
216
+ fig.add_trace(go.Scatter(
217
+ x=plotly_data[plotly_data2['Date'] == plotly_data2['Date'].max()][x_col],
218
+ y=plotly_data[plotly_data2['Date'] == plotly_data2['Date'].max()][y_col],
219
+ mode='markers',
220
+ marker=dict(
221
+ size=13 # Adjust the size value to make the markers larger or smaller
222
+ , color = 'yellow'
223
+ ),
224
+ name="Current Spends"
225
+ ))
226
+
227
+ fig.add_trace(go.Scatter(
228
+ x=[x_modified/104],
229
+ y=[y_modified/104],
230
+ mode='markers',
231
+ marker=dict(
232
+ size=13 # Adjust the size value to make the markers larger or smaller
233
+ , color = 'blue'
234
+ ),
235
+ name="Optimised Spends"
236
+ ))
237
+
238
+ # Update layout with titles
239
+ fig.update_layout(
240
+ title=channel+' Response Curve',
241
+ xaxis_title='Weekly Spends',
242
+ yaxis_title='Prospects'
243
+ )
244
+
245
+ # Show the figure
246
+ return fig
247
+
248
+ import pandas as pd
249
+ import numpy as np
250
+ import matplotlib.pyplot as plt
251
+ from scipy.optimize import curve_fit
252
+ from sklearn.preprocessing import MinMaxScaler
253
+ import warnings
254
+ warnings.filterwarnings("ignore")
255
+ import plotly.graph_objects as go
256
+
257
+ ## reading input data
258
+ df= pd.read_csv('response_curves_input_file.csv')
259
+ df.dropna(inplace=True)
260
+ df['Date'] = pd.to_datetime(df['Date'])
261
+ df.reset_index(inplace=True)
262
+
263
+ channel_cols = [
264
+ 'BroadcastTV',
265
+ 'CableTV',
266
+ 'Connected&OTTTV',
267
+ 'DisplayProspecting',
268
+ 'DisplayRetargeting',
269
+ 'Video',
270
+ 'SocialProspecting',
271
+ 'SocialRetargeting',
272
+ 'SearchBrand',
273
+ 'SearchNon-brand',
274
+ 'DigitalPartners',
275
+ 'Audio',
276
+ 'Email']
277
+ spend_cols = [
278
+ 'tv_broadcast_spend',
279
+ 'tv_cable_spend',
280
+ 'stream_video_spend',
281
+ 'disp_prospect_spend',
282
+ 'disp_retarget_spend',
283
+ 'olv_spend',
284
+ 'social_prospect_spend',
285
+ 'social_retarget_spend',
286
+ 'search_brand_spend',
287
+ 'search_nonbrand_spend',
288
+ 'cm_spend',
289
+ 'audio_spend',
290
+ 'email_spend']
291
+ prospect_cols = [
292
+ 'Broadcast TV_Prospects',
293
+ 'Cable TV_Prospects',
294
+ 'Connected & OTT TV_Prospects',
295
+ 'Display Prospecting_Prospects',
296
+ 'Display Retargeting_Prospects',
297
+ 'Video_Prospects',
298
+ 'Social Prospecting_Prospects',
299
+ 'Social Retargeting_Prospects',
300
+ 'Search Brand_Prospects',
301
+ 'Search Non-brand_Prospects',
302
+ 'Digital Partners_Prospects',
303
+ 'Audio_Prospects',
304
+ 'Email_Prospects']
305
+
306
+ def hill_equation(x, Kd, n):
307
+ return x**n / (Kd**n + x**n)
308
+
309
+
310
+ def hill_func(x_data,y_data,x_minmax,y_minmax):
311
+ # Fit the Hill equation to the data
312
+ initial_guess = [1, 1] # Initial guess for Kd and n
313
+ params, covariance = curve_fit(hill_equation, x_data, y_data, p0=initial_guess,maxfev = 1000)
314
+
315
+ # Extract the fitted parameters
316
+ Kd_fit, n_fit = params
317
+
318
+
319
+ # Generate y values using the fitted parameters
320
+ y_fit = hill_equation(x_data, Kd_fit, n_fit)
321
+
322
+ x_data_inv = x_minmax.inverse_transform(np.array(x_data).reshape(-1,1))
323
+ y_data_inv = y_minmax.inverse_transform(np.array(y_data).reshape(-1,1))
324
+ y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
325
+
326
+ # # Plot the original data and the fitted curve
327
+ # plt.scatter(x_data_inv, y_data_inv, label='Actual Data')
328
+ # plt.scatter(x_data_inv, y_fit_inv, label='Fit Data',color='red')
329
+ # # plt.line(x_data_inv, y_fit_inv, label=f'Fitted Hill Equation (Kd={Kd_fit:.2f}, n={n_fit:.2f})', color='red')
330
+ # plt.xlabel('Ligand Concentration')
331
+ # plt.ylabel('Fraction of Binding')
332
+ # plt.title('Fitting Hill Equation to Data')
333
+ # plt.legend()
334
+ # plt.show()
335
+
336
+ return y_fit,y_fit_inv,Kd_fit, n_fit
337
+
338
+ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
339
+ fit_col = 'Fit_Data_'+channel
340
+ plot_df = pd.DataFrame()
341
+
342
+ plot_df[f'{channel}_Spends'] = X
343
+
344
+ plot_df['Date'] = df['Date']
345
+ plot_df['MAT'] = df['MAT']
346
+
347
+
348
+
349
+ y_fit_inv_v2 = []
350
+ for i in range(len(y_fit_inv)):
351
+ y_fit_inv_v2.append(y_fit_inv[i][0])
352
+
353
+ plot_df[fit_col] = y_fit_inv_v2
354
+
355
+ # adding extra data
356
+
357
+ y_fit_inv_v2_ext = []
358
+ for i in range(len(y_fit_inv_ext)):
359
+ y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
360
+
361
+ # # # # print(x_ext_data)
362
+ ext_df = pd.DataFrame()
363
+ ext_df[f'{channel}_Spends'] = x_ext_data
364
+ ext_df[fit_col] = y_fit_inv_v2_ext
365
+
366
+ ext_df['Date'] = [
367
+ np.datetime64('1950-01-01'),
368
+ np.datetime64('1950-06-15'),
369
+ np.datetime64('1950-12-31')
370
+ ]
371
+
372
+ ext_df['MAT'] = ["ext","ext","ext"]
373
+
374
+ # # # # print(ext_df)
375
+ plot_df= plot_df.append(ext_df)
376
+ return plot_df
377
+
378
+ def input_data(df,spend_col,prospect_col):
379
+ X = np.array(df[spend_col].tolist())
380
+ y = np.array(df[prospect_col].tolist())
381
+
382
+ x_minmax = MinMaxScaler()
383
+ x_scaled = x_minmax.fit_transform(df[[spend_col]])
384
+ x_data = []
385
+ for i in range(len(x_scaled)):
386
+ x_data.append(x_scaled[i][0])
387
+
388
+ y_minmax = MinMaxScaler()
389
+ y_scaled = y_minmax.fit_transform(df[[prospect_col]])
390
+ y_data = []
391
+ for i in range(len(y_scaled)):
392
+ y_data.append(y_scaled[i][0])
393
+
394
+ return X,y,x_data,y_data,x_minmax,y_minmax
395
+
396
+ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
397
+ # # # # print(x_max)
398
+ x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
399
+ # x_ext_data = [1500000,2000000,2500000]
400
+ # x_ext_data = [x_max+100,x_max+200,x_max+5000]
401
+ x_scaled = x_minmax.transform(pd.DataFrame(x_ext_data))
402
+ x_data = []
403
+ for i in range(len(x_scaled)):
404
+ x_data.append(x_scaled[i][0])
405
+
406
+ # # # # print(x_data)
407
+ y_fit = hill_equation(x_data, Kd_fit, n_fit)
408
+ y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
409
+
410
+ return x_ext_data,y_fit_inv
411
+
412
+ def fit_data(spend_col,prospect_col,channel):
413
+ ### getting k and n parameters
414
+ temp_df = df[df[spend_col]>0]
415
+ temp_df.reset_index(inplace=True)
416
+
417
+ X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
418
+ y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
419
+ # # # # print('k: ',Kd_fit)
420
+ # # # # print('n: ', n_fit)
421
+
422
+ ##### extend_s_curve
423
+ x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
424
+
425
+ plot_df = data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext)
426
+ return plot_df
427
+
428
+ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
429
+ plotly_data.tail()
430
+
431
+ for i in range(1,13):
432
+ # # # # print(i)
433
+ pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
434
+ plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
435
+
436
+ def response_curves(channel,x_modified,y_modified):
437
+
438
+ # Initialize the Plotly figure
439
+ fig = go.Figure()
440
+
441
+ x_col = (channel+"_Spends").replace('\xa0', '')
442
+ y_col = ("Fit_Data_"+channel).replace('\xa0', '')
443
+
444
+ # fig.add_trace(go.Scatter(
445
+ # x=plotly_data[x_col],
446
+ # y=plotly_data[y_col],
447
+ # mode='markers',
448
+ # name=x_col.replace('_Spends', '')
449
+ # ))
450
+ plotly_data1 = plotly_data[plotly_data["MAT"]!="ext"]
451
+ fig.add_trace(go.Scatter(
452
+ x=plotly_data1.sort_values(by=x_col, ascending=True)[x_col],
453
+ y=plotly_data1.sort_values(by=x_col, ascending=True)[y_col],
454
+ mode='lines',
455
+ marker=dict(color = 'blue'),
456
+ name=x_col.replace('_Spends', '')
457
+ ))
458
+
459
+ dividing_parameter = len(plotly_data1[plotly_data1[x_col].isnull()==False])
460
+ # print(dividing_parameter)
461
+ plotly_data2 = plotly_data.copy()
462
+ plotly_data2 = plotly_data[plotly_data[x_col].isnull()==False]
463
+ plotly_data2 = plotly_data2[plotly_data2["MAT"]!="ext"]
464
+ # .dropna(subset=[x_col]).reset_index(inplace = True)
465
+ fig.add_trace(go.Scatter(
466
+ x=np.array(plotly_data2[x_col].mean()),
467
+ y=np.array(plotly_data2[y_col].mean()),
468
+ mode='markers',
469
+ marker=dict(
470
+ size=13 # Adjust the size value to make the markers larger or smaller
471
+ , color = '#516DA6'
472
+ ),
473
+ name="Current Spends"
474
+ ))
475
+
476
+ # # print(dividing_parameter)
477
+ fig.add_trace(go.Scatter(
478
+ x=[x_modified/dividing_parameter],
479
+ y=[y_modified/dividing_parameter],
480
+ mode='markers',
481
+ marker=dict(
482
+ size=13 # Adjust the size value to make the markers larger or smaller
483
+ , color = '#4ACAD9'
484
+ ),
485
+ name="Optimised Spends"
486
+ ))
487
+
488
+ # Update layout with titles
489
+ fig.update_layout(
490
+ title={
491
+ 'text': channel_name_formating(channel)+' Response Curve',
492
+ 'font': {
493
+ 'size': 24,
494
+ 'family': 'Arial',
495
+ 'color': 'black',
496
+ # 'bold': True
497
+ }
498
+ },
499
+ # title=channel_name_formating(channel)+' Response Curve',
500
+ xaxis_title='Weekly Spends',
501
+ yaxis_title='Prospects'
502
+ )
503
+
504
+ # Show the figure
505
+ return fig
506
+
response_curves_model_quality_base.py ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ from scipy.optimize import curve_fit
5
+ from sklearn.preprocessing import MinMaxScaler
6
+ import warnings
7
+ warnings.filterwarnings("ignore")
8
+ import plotly.graph_objects as go
9
+ from utilities_with_panel import (channel_name_formating)
10
+ ## reading input data
11
+ df= pd.read_csv('response_curves_input_file.csv')
12
+ df.dropna(inplace=True)
13
+ df['Date'] = pd.to_datetime(df['Date'])
14
+ df.reset_index(inplace=True)
15
+ import random
16
+ channel_cols = [
17
+ 'Broadcast TV',
18
+ 'Cable TV',
19
+ 'Connected & OTT TV',
20
+ 'Display Prospecting',
21
+ 'Display Retargeting',
22
+ 'Video',
23
+ 'Social Prospecting',
24
+ 'Social Retargeting',
25
+ 'Search Brand',
26
+ 'Search Non-brand',
27
+ 'Digital Partners',
28
+ 'Audio',
29
+ 'Email']
30
+ spend_cols = [
31
+ 'tv_broadcast_spend',
32
+ 'tv_cable_spend',
33
+ 'stream_video_spend',
34
+ 'disp_prospect_spend',
35
+ 'disp_retarget_spend',
36
+ 'olv_spend',
37
+ 'social_prospect_spend',
38
+ 'social_retarget_spend',
39
+ 'search_brand_spend',
40
+ 'search_nonbrand_spend',
41
+ 'cm_spend',
42
+ 'audio_spend',
43
+ 'email_spend']
44
+ prospect_cols = [
45
+ 'Broadcast TV_Prospects',
46
+ 'Cable TV_Prospects',
47
+ 'Connected & OTT TV_Prospects',
48
+ 'Display Prospecting_Prospects',
49
+ 'Display Retargeting_Prospects',
50
+ 'Video_Prospects',
51
+ 'Social Prospecting_Prospects',
52
+ 'Social Retargeting_Prospects',
53
+ 'Search Brand_Prospects',
54
+ 'Search Non-brand_Prospects',
55
+ 'Digital Partners_Prospects',
56
+ 'Audio_Prospects',
57
+ 'Email_Prospects']
58
+
59
+ def hill_equation(x, Kd, n):
60
+ return x**n / (Kd**n + x**n)
61
+
62
+
63
+ def hill_func(x_data,y_data,x_minmax,y_minmax):
64
+ # Fit the Hill equation to the data
65
+ initial_guess = [1, 1] # Initial guess for Kd and n
66
+ params, covariance = curve_fit(hill_equation, x_data, y_data, p0=initial_guess,maxfev = 1000)
67
+
68
+ # Extract the fitted parameters
69
+ Kd_fit, n_fit = params
70
+
71
+
72
+ # Generate y values using the fitted parameters
73
+ y_fit = hill_equation(x_data, Kd_fit, n_fit)
74
+
75
+ x_data_inv = x_minmax.inverse_transform(np.array(x_data).reshape(-1,1))
76
+ y_data_inv = y_minmax.inverse_transform(np.array(y_data).reshape(-1,1))
77
+ y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
78
+
79
+ # # Plot the original data and the fitted curve
80
+ # plt.scatter(x_data_inv, y_data_inv, label='Actual Data')
81
+ # plt.scatter(x_data_inv, y_fit_inv, label='Fit Data',color='red')
82
+ # # plt.line(x_data_inv, y_fit_inv, label=f'Fitted Hill Equation (Kd={Kd_fit:.2f}, n={n_fit:.2f})', color='red')
83
+ # plt.xlabel('Ligand Concentration')
84
+ # plt.ylabel('Fraction of Binding')
85
+ # plt.title('Fitting Hill Equation to Data')
86
+ # plt.legend()
87
+ # plt.show()
88
+
89
+ return y_fit,y_fit_inv,Kd_fit, n_fit
90
+
91
+ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
92
+ fit_col = 'Fit_Data_'+channel
93
+ plot_df = pd.DataFrame()
94
+
95
+ plot_df[f'{channel}_Spends'] = X
96
+ plot_df[f'{channel}_Prospects'] = y
97
+ plot_df['Date'] = df['Date']
98
+ plot_df['MAT'] = df['MAT']
99
+
100
+
101
+
102
+ y_fit_inv_v2 = []
103
+ for i in range(len(y_fit_inv)):
104
+ y_fit_inv_v2.append(y_fit_inv[i][0])
105
+
106
+ plot_df[fit_col] = y_fit_inv_v2
107
+
108
+ # adding extra data
109
+
110
+ y_fit_inv_v2_ext = []
111
+ for i in range(len(y_fit_inv_ext)):
112
+ y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
113
+
114
+ # # # # print(x_ext_data)
115
+ ext_df = pd.DataFrame()
116
+ ext_df[f'{channel}_Spends'] = x_ext_data
117
+ ext_df[f'{channel}_Prospects'] = y_fit_inv_v2_ext
118
+ ext_df[fit_col] = y_fit_inv_v2_ext
119
+
120
+ ext_df['Date'] = [
121
+ np.datetime64('1950-01-01'),
122
+ np.datetime64('1950-06-15'),
123
+ np.datetime64('1950-12-31')
124
+ ]
125
+
126
+ ext_df['MAT'] = ["ext","ext","ext"]
127
+
128
+ # # # # print(ext_df.columns)
129
+ plot_df= plot_df.append(ext_df)
130
+ return plot_df
131
+
132
+ def input_data(df,spend_col,prospect_col):
133
+ X = np.array(df[spend_col].tolist())
134
+ y = np.array(df[prospect_col].tolist())
135
+
136
+ x_minmax = MinMaxScaler()
137
+ x_scaled = x_minmax.fit_transform(df[[spend_col]])
138
+ x_data = []
139
+ for i in range(len(x_scaled)):
140
+ x_data.append(x_scaled[i][0])
141
+
142
+ y_minmax = MinMaxScaler()
143
+ y_scaled = y_minmax.fit_transform(df[[prospect_col]])
144
+ y_data = []
145
+ for i in range(len(y_scaled)):
146
+ y_data.append(y_scaled[i][0])
147
+
148
+ return X,y,x_data,y_data,x_minmax,y_minmax
149
+
150
+ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
151
+ # # # # print(x_max)
152
+ x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
153
+ # x_ext_data = [1500000,2000000,2500000]
154
+ # x_ext_data = [x_max+100,x_max+200,x_max+5000]
155
+ x_scaled = x_minmax.transform(pd.DataFrame(x_ext_data))
156
+ x_data = []
157
+ for i in range(len(x_scaled)):
158
+ x_data.append(x_scaled[i][0])
159
+
160
+ # # # # print(x_data)
161
+ y_fit = hill_equation(x_data, Kd_fit, n_fit)
162
+ y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
163
+
164
+ return x_ext_data,y_fit_inv
165
+
166
+ def fit_data(spend_col,prospect_col,channel):
167
+ ### getting k and n parameters
168
+ temp_df = df[df[spend_col]>0]
169
+ temp_df.reset_index(inplace=True)
170
+
171
+ X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
172
+ y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
173
+ # # # # print('k: ',Kd_fit)
174
+ # # # # print('n: ', n_fit)
175
+
176
+ ##### extend_s_curve
177
+ x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
178
+
179
+ plot_df = data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext)
180
+ return plot_df
181
+
182
+ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
183
+ plotly_data.tail()
184
+
185
+ for i in range(1,13):
186
+ # # # print(i)
187
+ pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
188
+ plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
189
+
190
+ def response_curves(channel,chart_typ):
191
+ if chart_typ == 'View Scattered Plot':
192
+ mode_f1 = "markers"
193
+ # Initialize the Plotly figure
194
+ fig = go.Figure()
195
+
196
+ x_col = channel+"_Spends"
197
+ y_col = channel+"_Prospects"
198
+ fig.add_trace(go.Scatter(
199
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
200
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
201
+ mode=mode_f1,
202
+ name=x_col.replace('_Spends', '')
203
+ ))
204
+ elif chart_typ == 'View Line Plot':
205
+ mode_f1 = "lines"
206
+ # Initialize the Plotly figure
207
+ fig = go.Figure()
208
+
209
+ x_col = channel+"_Spends"
210
+ y_col = 'Fit_Data_'+channel
211
+ fig.add_trace(go.Scatter(
212
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
213
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
214
+ mode=mode_f1,
215
+ name=x_col.replace('_Spends', '')
216
+ ,line=dict(color='#4B88FF')
217
+ ))
218
+ else:
219
+ mode_f1 = "markers"
220
+ # Initialize the Plotly figure
221
+ fig = go.Figure()
222
+
223
+ x_col = channel+"_Spends"
224
+ y_col = channel+"_Prospects"
225
+ fig.add_trace(go.Scatter(
226
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
227
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
228
+ mode=mode_f1,
229
+ name=x_col.replace('_Spends', '')
230
+ ))
231
+
232
+ # mode_f1 = "lines+markers"
233
+ mode_f1 = "lines"
234
+ # Initialize the Plotly figure
235
+ # fig = go.Figure()
236
+
237
+ x_col = channel+"_Spends"
238
+ y_col = 'Fit_Data_'+channel
239
+ fig.add_trace(go.Scatter(
240
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
241
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
242
+ mode=mode_f1,
243
+ name=x_col.replace('_Spends', '')
244
+ ,line=dict(color='#4B88FF')
245
+ ))
246
+
247
+
248
+ plotly_data2 = plotly_data[plotly_data[x_col].isnull()==False]
249
+ plotly_data2 = plotly_data2[plotly_data2["MAT"]!="ext"]
250
+ # # # print(plotly_data2[x_col].mean(),plotly_data2[y_col].mean())
251
+ # import steamlit as st
252
+ # st.dataframe()
253
+ fig.add_trace(go.Scatter(
254
+ x=np.array(plotly_data2[x_col].mean()),
255
+ y=np.array(plotly_data2['Fit_Data_'+channel].mean()),
256
+ mode='markers',
257
+ marker=dict(
258
+ size=13 # Adjust the size value to make the markers larger or smaller
259
+ , color = 'green'
260
+ ),
261
+ name="Average Weekly Spends"
262
+ ))
263
+
264
+ # Update layout with titles
265
+ fig.update_layout(
266
+ width=700, height=500,
267
+ title={
268
+ 'text': channel_name_formating(channel)+' Response Curve',
269
+ 'font': {
270
+ 'size': 24,
271
+ 'family': 'Arial',
272
+ 'color': 'black',
273
+ # 'bold': True
274
+ }
275
+ },
276
+ # title=channel_name_formating(channel)+' Response Curve',
277
+ xaxis_title='Weekly Spends',
278
+ yaxis_title='Prospects'
279
+ )
280
+
281
+ # Show the figure
282
+ return fig
283
+
response_curves_parameters.xlsx ADDED
Binary file (11.3 kB). View file
 
setup.sh ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Install dependencies from requirements.txt
2
+ pip install -r requirements.txt
3
+
4
+ # Install Orca using Conda
5
+ conda install -c plotly plotly-orca
6
+
7
+ # Verify Orca installation
8
+ which orca
styles.css ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ html {
2
+ margin: 0;
3
+ }
4
+
5
+
6
+ #MainMenu {
7
+
8
+ visibility: collapse;
9
+ }
10
+
11
+ footer {
12
+ visibility: collapse;
13
+ }
14
+
15
+ div.block-container{
16
+ padding: 2rem 3rem;
17
+ }
18
+
19
+ div[data-testid="stExpander"]{
20
+ border: 1px solid '#739FAE';
21
+ }
22
+
23
+ hr{
24
+ margin: 0;
25
+ padding: 0;
26
+ }
27
+
28
+ hr.spends-heading-seperator {
29
+ background-color : #11B6BD;
30
+ height: 2px;
31
+ }
32
+
33
+ .spends-header{
34
+ font-size: 1rem;
35
+ font-weight: bold;
36
+ margin: 0;
37
+
38
+ }
39
+
40
+ td {
41
+ max-width: 100px;
42
+ /* white-space:nowrap; */
43
+ }
44
+
45
+ .main-header {
46
+ display: flex;
47
+ flex-direction: row;
48
+ justify-content: space-between;
49
+ align-items: center;
50
+
51
+ }
52
+ .blend-logo {
53
+ max-height: 64px;
54
+ /* max-width: 300px; */
55
+ object-fit: cover;
56
+ }
57
+
58
+ table {
59
+ width: 90%;
60
+ }
61
+
62
+ .lime-logo {
63
+ margin: 0;
64
+ padding: 0;
65
+ display: flex;
66
+ align-items: center ;
67
+ max-height: 64px;
68
+ }
69
+
70
+ .lime-text {
71
+ color: #00EDED;
72
+ font-size: 30px;
73
+ margin: 0;
74
+ padding: 0;
75
+ line-height: 0%;
76
+ }
77
+
78
+ .lime-img {
79
+ max-height: 30px;
80
+ /* max-height: 64px; */
81
+ /* max-width: 300px; */
82
+ object-fit: cover;
83
+ }
84
+
85
+ img {
86
+ margin: 0;
87
+ padding: 0;
88
+ }
summary_df.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3903995f3ab1eb9b34db90db9d8177955cff0a37af45969c97543cc82909a170
3
+ size 1822
tuned_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:04ad6063f8ede7a8d6820388b8aca610d5f2082434ce7b16efaf56b419148a58
3
+ size 4223912
utilities.py ADDED
@@ -0,0 +1,796 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from numerize.numerize import numerize
2
+ import streamlit as st
3
+ import pandas as pd
4
+ import json
5
+ from classes import Channel, Scenario
6
+ import numpy as np
7
+ from plotly.subplots import make_subplots
8
+ import plotly.graph_objects as go
9
+ from classes import class_to_dict
10
+ from collections import OrderedDict
11
+ import io
12
+ import plotly
13
+ from pathlib import Path
14
+ import pickle
15
+ import yaml
16
+ from yaml import SafeLoader
17
+ from streamlit.components.v1 import html
18
+ import smtplib
19
+ from scipy.optimize import curve_fit
20
+ from sklearn.metrics import r2_score
21
+ from classes import class_from_dict
22
+ import os
23
+ import base64
24
+
25
+
26
+ color_palette = [
27
+ "#F3F3F0",
28
+ "#5E7D7E",
29
+ "#2FA1FF",
30
+ "#00EDED",
31
+ "#00EAE4",
32
+ "#304550",
33
+ "#EDEBEB",
34
+ "#7FBEFD",
35
+ "#003059",
36
+ "#A2F3F3",
37
+ "#E1D6E2",
38
+ "#B6B6B6",
39
+ ]
40
+
41
+
42
+ CURRENCY_INDICATOR = '$'
43
+
44
+ import streamlit_authenticator as stauth
45
+
46
+
47
+ def load_authenticator():
48
+ with open("config.yaml") as file:
49
+ config = yaml.load(file, Loader=SafeLoader)
50
+ st.session_state["config"] = config
51
+ authenticator = stauth.Authenticate(
52
+ credentials=config["credentials"],
53
+ cookie_name=config["cookie"]["name"],
54
+ key=config["cookie"]["key"],
55
+ cookie_expiry_days=config["cookie"]["expiry_days"],
56
+ preauthorized=config["preauthorized"],
57
+ )
58
+ st.session_state["authenticator"] = authenticator
59
+ return authenticator
60
+
61
+
62
+ # Authentication
63
+ def authentication():
64
+ with open("config.yaml") as file:
65
+ config = yaml.load(file, Loader=SafeLoader)
66
+
67
+ authenticator = stauth.Authenticate(
68
+ config["credentials"],
69
+ config["cookie"]["name"],
70
+ config["cookie"]["key"],
71
+ config["cookie"]["expiry_days"],
72
+ config["preauthorized"],
73
+ )
74
+
75
+ name, authentication_status, username = authenticator.login("Login", "main")
76
+ return authenticator, name, authentication_status, username
77
+
78
+
79
+ def nav_page(page_name, timeout_secs=3):
80
+ nav_script = """
81
+ <script type="text/javascript">
82
+ function attempt_nav_page(page_name, start_time, timeout_secs) {
83
+ var links = window.parent.document.getElementsByTagName("a");
84
+ for (var i = 0; i < links.length; i++) {
85
+ if (links[i].href.toLowerCase().endsWith("/" + page_name.toLowerCase())) {
86
+ links[i].click();
87
+ return;
88
+ }
89
+ }
90
+ var elasped = new Date() - start_time;
91
+ if (elasped < timeout_secs * 1000) {
92
+ setTimeout(attempt_nav_page, 100, page_name, start_time, timeout_secs);
93
+ } else {
94
+ alert("Unable to navigate to page '" + page_name + "' after " + timeout_secs + " second(s).");
95
+ }
96
+ }
97
+ window.addEventListener("load", function() {
98
+ attempt_nav_page("%s", new Date(), %d);
99
+ });
100
+ </script>
101
+ """ % (
102
+ page_name,
103
+ timeout_secs,
104
+ )
105
+ html(nav_script)
106
+
107
+
108
+ # def load_local_css(file_name):
109
+ # with open(file_name) as f:
110
+ # st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
111
+
112
+
113
+ # def set_header():
114
+ # return st.markdown(f"""<div class='main-header'>
115
+ # <h1>MMM LiME</h1>
116
+ # <img src="https://assets-global.website-files.com/64c8fffb0e95cbc525815b79/64df84637f83a891c1473c51_Vector%20(Stroke).svg ">
117
+ # </div>""", unsafe_allow_html=True)
118
+
119
+ path = os.path.dirname(__file__)
120
+
121
+ file_ = open(f"{path}/ALDI_2017.png", "rb")
122
+
123
+ contents = file_.read()
124
+
125
+ data_url = base64.b64encode(contents).decode("utf-8")
126
+
127
+ file_.close()
128
+
129
+
130
+ DATA_PATH = "./data"
131
+
132
+ IMAGES_PATH = "./data/images_224_224"
133
+
134
+
135
+ def load_local_css(file_name):
136
+
137
+ with open(file_name) as f:
138
+
139
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
140
+
141
+
142
+ # def set_header():
143
+
144
+ # return st.markdown(f"""<div class='main-header'>
145
+
146
+ # <h1>H & M Recommendations</h1>
147
+
148
+ # <img src="data:image;base64,{data_url}", alt="Logo">
149
+
150
+ # </div>""", unsafe_allow_html=True)
151
+ path1 = os.path.dirname(__file__)
152
+
153
+ file_1 = open(f"{path}/ALDI_2017.png", "rb")
154
+
155
+ contents1 = file_1.read()
156
+
157
+ data_url1 = base64.b64encode(contents1).decode("utf-8")
158
+
159
+ file_1.close()
160
+
161
+
162
+ DATA_PATH1 = "./data"
163
+
164
+ IMAGES_PATH1 = "./data/images_224_224"
165
+
166
+
167
+ def set_header():
168
+ return st.markdown(
169
+ f"""<div class='main-header'>
170
+ <!-- <h1></h1> -->
171
+ <div >
172
+ <img class='blend-logo' src="data:image;base64,{data_url1}", alt="Logo">
173
+ </div>""",
174
+ unsafe_allow_html=True,
175
+ )
176
+
177
+
178
+ # def set_header():
179
+ # logo_path = "./path/to/your/local/LIME_logo.png" # Replace with the actual file path
180
+ # text = "LiME"
181
+ # return st.markdown(f"""<div class='main-header'>
182
+ # <img src="data:image/png;base64,{data_url}" alt="Logo" style="float: left; margin-right: 10px; width: 100px; height: auto;">
183
+ # <h1>{text}</h1>
184
+ # </div>""", unsafe_allow_html=True)
185
+
186
+
187
+ def s_curve(x, K, b, a, x0):
188
+ return K / (1 + b * np.exp(-a * (x - x0)))
189
+
190
+
191
+ def panel_level(input_df, date_column="Date"):
192
+ # Ensure 'Date' is set as the index
193
+ if date_column not in input_df.index.names:
194
+ input_df = input_df.set_index(date_column)
195
+
196
+ # Select numeric columns only (excluding 'Date' since it's now the index)
197
+ numeric_columns_df = input_df.select_dtypes(include="number")
198
+
199
+ # Group by 'Date' (which is the index) and sum the numeric columns
200
+ aggregated_df = numeric_columns_df.groupby(input_df.index).sum()
201
+
202
+ # Reset index if you want 'Date' back as a column
203
+ aggregated_df = aggregated_df.reset_index()
204
+
205
+ return aggregated_df
206
+
207
+
208
+ def initialize_data(
209
+ target_file, panel=None, updated_rcs=None, metrics=None
210
+ ):
211
+ # uopx_conv_rates = {'streaming_impressions' : 0.007,'digital_impressions' : 0.007,'search_clicks' : 0.00719,'tv_impressions' : 0.000173,
212
+ # "digital_clicks":0.005,"streaming_clicks":0.004,'streaming_spends':1,"tv_spends":1,"search_spends":1,
213
+ # "digital_spends":1}
214
+ # # # # print('State initialized')
215
+
216
+ excel = pd.read_excel(target_file, sheet_name=None)
217
+
218
+ # Extract dataframes for raw data, spend input, and contribution MMM
219
+ raw_df = excel["RAW DATA MMM"]
220
+ spend_df = excel["SPEND INPUT"]
221
+ contri_df = excel["CONTRIBUTION MMM"]
222
+
223
+ # Check if the panel is not None
224
+
225
+ raw_df = panel_level(raw_df, date_column="Date")
226
+ spend_df = panel_level(spend_df, date_column="Week")
227
+ contri_df = panel_level(contri_df, date_column="Date")
228
+
229
+ # Revenue_df = excel['Revenue']
230
+
231
+ ## remove sesonalities, indices etc ...
232
+ exclude_columns = [
233
+ "Date",
234
+ "Region",
235
+ "Controls_Grammarly_Index_SeasonalAVG",
236
+ "Controls_Quillbot_Index",
237
+ "Daily_Positive_Outliers",
238
+ "External_RemoteClass_Index",
239
+ "Intervals ON 20190520-20190805 | 20200518-20200803 | 20210517-20210802",
240
+ "Intervals ON 20190826-20191209 | 20200824-20201207 | 20210823-20211206",
241
+ "Intervals ON 20201005-20201019",
242
+ "Promotion_PercentOff",
243
+ "Promotion_TimeBased",
244
+ "Seasonality_Indicator_Chirstmas",
245
+ "Seasonality_Indicator_NewYears_Days",
246
+ "Seasonality_Indicator_Thanksgiving",
247
+ "Trend 20200302 / 20200803",
248
+ ]
249
+ raw_df["Date"] = pd.to_datetime(raw_df["Date"])
250
+ contri_df["Date"] = pd.to_datetime(contri_df["Date"])
251
+ input_df = raw_df.sort_values(by="Date")
252
+ output_df = contri_df.sort_values(by="Date")
253
+ spend_df["Week"] = pd.to_datetime(
254
+ spend_df["Week"], format="%Y-%m-%d", errors="coerce"
255
+ )
256
+ spend_df.sort_values(by="Week", inplace=True)
257
+
258
+ # spend_df['Week'] = pd.to_datetime(spend_df['Week'], errors='coerce')
259
+ # spend_df = spend_df.sort_values(by='Week')
260
+
261
+ channel_list = [col for col in input_df.columns if col not in exclude_columns]
262
+ channel_list = list(set(channel_list) - set(["fb_level_achieved_tier_1", "ga_app"]))
263
+
264
+ response_curves = {}
265
+ mapes = {}
266
+ rmses = {}
267
+ upper_limits = {}
268
+ powers = {}
269
+ r2 = {}
270
+ conv_rates = {}
271
+ output_cols = []
272
+ channels = {}
273
+ sales = None
274
+ dates = input_df.Date.values
275
+ actual_output_dic = {}
276
+ actual_input_dic = {}
277
+
278
+ for inp_col in channel_list:
279
+ # st.write(inp_col)
280
+ spends = input_df[inp_col].values
281
+ x = spends.copy()
282
+ # upper limit for penalty
283
+ upper_limits[inp_col] = 2 * x.max()
284
+
285
+ # contribution
286
+ out_col = [_col for _col in output_df.columns if _col.startswith(inp_col)][0]
287
+ y = output_df[out_col].values.copy()
288
+ actual_output_dic[inp_col] = y.copy()
289
+ actual_input_dic[inp_col] = x.copy()
290
+ ##output cols aggregation
291
+ output_cols.append(out_col)
292
+
293
+ params = pd.read_excel("response_curves_parameters.xlsx",index_col = "channel")
294
+ param_dicts = {col: params[col].to_dict() for col in params.columns}
295
+ response_curves[inp_col] = {
296
+ "Kd": param_dicts["Kd"][inp_col],
297
+ "n": param_dicts["n"][inp_col],
298
+ "x_min": param_dicts["x_min"][inp_col],
299
+ "x_max": param_dicts["x_max"][inp_col],
300
+ "y_min": param_dicts["y_min"][inp_col],
301
+ "y_max": param_dicts["y_max"][inp_col]
302
+ }
303
+
304
+ updated_rcs_key = f"{metrics}#@{panel}#@{inp_col}"
305
+ if updated_rcs is not None and updated_rcs_key in list(updated_rcs.keys()):
306
+ response_curves[inp_col] = updated_rcs[updated_rcs_key]
307
+
308
+ # # # # print(response_curves)
309
+ ## conversion rates
310
+ spend_col = [
311
+ _col
312
+ for _col in spend_df.columns
313
+ if _col.startswith(inp_col.rsplit("_", 1)[0])
314
+ ][0]
315
+ # # # # print(spend_col)
316
+ # # # # print('## # # printing spendssss')
317
+ # # # # print(spend_col)
318
+ conv = (
319
+ spend_df.set_index("Week")[spend_col]
320
+ / input_df.set_index("Date")[inp_col].clip(lower=1)
321
+ ).reset_index()
322
+ conv.rename(columns={"index": "Week"}, inplace=True)
323
+ conv["year"] = conv.Week.dt.year
324
+ conv_rates[inp_col] = list(conv.drop("Week", axis=1).mean().to_dict().values())[
325
+ 0
326
+ ]
327
+ # # # # print(conv_rates)
328
+ ### # # print('Before',conv_rates[inp_col])
329
+ # conv_rates[inp_col] = uopx_conv_rates[inp_col]
330
+ ### # # print('After',(conv_rates[inp_col]))
331
+
332
+ channel = Channel(
333
+ name=inp_col,
334
+ dates=dates,
335
+ spends=spends,
336
+ sales= y.copy(),
337
+ # conversion_rate = np.mean(list(conv_rates[inp_col].values())),
338
+ conversion_rate=1.0 ,#conv_rates[inp_col],
339
+ response_curve_type="hill-eq",
340
+ response_curve_params={
341
+ "Kd": param_dicts["Kd"][inp_col],
342
+ "n": param_dicts["n"][inp_col],
343
+ "x_min": param_dicts["x_min"][inp_col],
344
+ "x_max": param_dicts["x_max"][inp_col],
345
+ "y_min": param_dicts["y_min"][inp_col],
346
+ "y_max": param_dicts["y_max"][inp_col],
347
+ "num_pos_obsv":param_dicts["num_pos_obsv"][inp_col]
348
+ },
349
+ bounds=np.array([-10, 10]),
350
+ channel_bounds_min = round(param_dicts["x_min"][inp_col]*100*param_dicts["num_pos_obsv"][inp_col]/param_dicts["current_spends"][inp_col]),
351
+ channel_bounds_max = 100
352
+ )
353
+ channels[inp_col] = channel
354
+ if sales is None:
355
+ sales = channel.actual_sales
356
+ else:
357
+ sales += channel.actual_sales
358
+ # # # # print(actual_output_dic)
359
+ other_contributions = (
360
+ output_df.drop([*output_cols], axis=1).sum(axis=1, numeric_only=True).values
361
+ )
362
+ correction = output_df.drop("Date", axis=1).sum(axis=1).values - (sales + other_contributions)
363
+ # # # # print(other_contributions)
364
+ # # # # print(correction)
365
+ scenario = Scenario(
366
+ name="default",
367
+ channels=channels,
368
+ constant=other_contributions,
369
+ correction=correction,
370
+ )
371
+ ## setting session variables
372
+ st.session_state["initialized"] = True
373
+ st.session_state["actual_df"] = input_df
374
+ st.session_state["raw_df"] = raw_df
375
+ st.session_state["contri_df"] = output_df
376
+ default_scenario_dict = class_to_dict(scenario)
377
+ st.session_state["default_scenario_dict"] = default_scenario_dict
378
+ st.session_state["scenario"] = scenario
379
+ st.session_state["channels_list"] = channel_list
380
+ st.session_state["optimization_channels"] = {
381
+ channel_name: False for channel_name in channel_list
382
+ }
383
+ st.session_state["rcs"] = response_curves
384
+
385
+ st.session_state["powers"] = powers
386
+ st.session_state["actual_contribution_df"] = pd.DataFrame(actual_output_dic)
387
+ st.session_state["actual_input_df"] = pd.DataFrame(actual_input_dic)
388
+
389
+ for channel in channels.values():
390
+ st.session_state[channel.name] = numerize(
391
+ channel.actual_total_spends * 1.0, 1
392
+ )
393
+
394
+ st.session_state["xlsx_buffer"] = io.BytesIO()
395
+
396
+ if Path("../saved_scenarios.pkl").exists():
397
+ with open("../saved_scenarios.pkl", "rb") as f:
398
+ st.session_state["saved_scenarios"] = pickle.load(f)
399
+ else:
400
+ st.session_state["saved_scenarios"] = OrderedDict()
401
+
402
+ # st.session_state["total_spends_change"] = 0
403
+ st.session_state["optimization_channels"] = {
404
+ channel_name: False for channel_name in channel_list
405
+ }
406
+ st.session_state["disable_download_button"] = True
407
+ # if target_file == :
408
+ # st.session_state["dividing_parameter"] =
409
+ # else :
410
+
411
+
412
+
413
+ def create_channel_summary(scenario):
414
+
415
+ # Provided data
416
+ data = {
417
+ "Channel": [
418
+ "Paid Search",
419
+ "Ga will cid baixo risco",
420
+ "Digital tactic others",
421
+ "Fb la tier 1",
422
+ "Fb la tier 2",
423
+ "Paid social others",
424
+ "Programmatic",
425
+ "Kwai",
426
+ "Indicacao",
427
+ "Infleux",
428
+ "Influencer",
429
+ ],
430
+ "Spends": [
431
+ "$ 11.3K",
432
+ "$ 155.2K",
433
+ "$ 50.7K",
434
+ "$ 125.4K",
435
+ "$ 125.2K",
436
+ "$ 105K",
437
+ "$ 3.3M",
438
+ "$ 47.5K",
439
+ "$ 55.9K",
440
+ "$ 632.3K",
441
+ "$ 48.3K",
442
+ ],
443
+ "Revenue": [
444
+ "558.0K",
445
+ "3.5M",
446
+ "5.2M",
447
+ "3.1M",
448
+ "3.1M",
449
+ "2.1M",
450
+ "20.8M",
451
+ "1.6M",
452
+ "728.4K",
453
+ "22.9M",
454
+ "4.8M",
455
+ ],
456
+ }
457
+
458
+ # Create DataFrame
459
+ df = pd.DataFrame(data)
460
+
461
+ # Convert currency strings to numeric values
462
+ df["Spends"] = (
463
+ df["Spends"]
464
+ .replace({"\$": "", "K": "*1e3", "M": "*1e6"}, regex=True)
465
+ .map(pd.eval)
466
+ .astype(int)
467
+ )
468
+ df["Revenue"] = (
469
+ df["Revenue"]
470
+ .replace({"\$": "", "K": "*1e3", "M": "*1e6"}, regex=True)
471
+ .map(pd.eval)
472
+ .astype(int)
473
+ )
474
+
475
+ # Calculate ROI
476
+ df["ROI"] = (df["Revenue"] - df["Spends"]) / df["Spends"]
477
+
478
+ # Format columns
479
+ format_currency = lambda x: f"${x:,.1f}"
480
+ format_roi = lambda x: f"{x:.1f}"
481
+
482
+ df["Spends"] = [
483
+ "$ 11.3K",
484
+ "$ 155.2K",
485
+ "$ 50.7K",
486
+ "$ 125.4K",
487
+ "$ 125.2K",
488
+ "$ 105K",
489
+ "$ 3.3M",
490
+ "$ 47.5K",
491
+ "$ 55.9K",
492
+ "$ 632.3K",
493
+ "$ 48.3K",
494
+ ]
495
+ df["Revenue"] = [
496
+ "$ 536.3K",
497
+ "$ 3.4M",
498
+ "$ 5M",
499
+ "$ 3M",
500
+ "$ 3M",
501
+ "$ 2M",
502
+ "$ 20M",
503
+ "$ 1.5M",
504
+ "$ 7.1M",
505
+ "$ 22M",
506
+ "$ 4.6M",
507
+ ]
508
+ df["ROI"] = df["ROI"].apply(format_roi)
509
+
510
+ return df
511
+
512
+
513
+
514
+ def create_contribution_pie():
515
+ color_palette = [
516
+ "#F3F3F0",
517
+ "#5E7D7E",
518
+ "#2FA1FF",
519
+ "#00EDED",
520
+ "#00EAE4",
521
+ "#304550",
522
+ "#EDEBEB",
523
+ "#7FBEFD",
524
+ "#003059",
525
+ "#A2F3F3",
526
+ "#E1D6E2",
527
+ "#B6B6B6",
528
+ ]
529
+ total_contribution_fig = make_subplots(
530
+ rows=1,
531
+ cols=2,
532
+ subplot_titles=["Spends", "Revenue"],
533
+ specs=[[{"type": "pie"}, {"type": "pie"}]],
534
+ )
535
+
536
+ channels_list = [
537
+ "Paid Search",
538
+ "Ga will cid baixo risco",
539
+ "Digital tactic others",
540
+ "Fb la tier 1",
541
+ "Fb la tier 2",
542
+ "Paid social others",
543
+ "Programmatic",
544
+ "Kwai",
545
+ "Indicacao",
546
+ "Infleux",
547
+ "Influencer",
548
+ "Non Media",
549
+ ]
550
+
551
+ # Assign colors from the limited palette to channels
552
+ colors_map = {
553
+ col: color_palette[i % len(color_palette)]
554
+ for i, col in enumerate(channels_list)
555
+ }
556
+ colors_map["Non Media"] = color_palette[
557
+ 5
558
+ ] # Assign fixed green color for 'Non Media'
559
+
560
+ # Hardcoded values for Spends and Revenue
561
+ spends_values = [0.5, 3.36, 1.1, 2.7, 2.7, 2.27, 70.6, 1, 1, 13.7, 1, 0]
562
+ revenue_values = [1, 4, 5, 3, 3, 2, 50.8, 1.5, 0.7, 13, 0, 16]
563
+
564
+ # Add trace for Spends pie chart
565
+ total_contribution_fig.add_trace(
566
+ go.Pie(
567
+ labels=[channel_name for channel_name in channels_list],
568
+ values=spends_values,
569
+ marker=dict(
570
+ colors=[colors_map[channel_name] for channel_name in channels_list]
571
+ ),
572
+ hole=0.3,
573
+ ),
574
+ row=1,
575
+ col=1,
576
+ )
577
+
578
+ # Add trace for Revenue pie chart
579
+ total_contribution_fig.add_trace(
580
+ go.Pie(
581
+ labels=[channel_name for channel_name in channels_list],
582
+ values=revenue_values,
583
+ marker=dict(
584
+ colors=[colors_map[channel_name] for channel_name in channels_list]
585
+ ),
586
+ hole=0.3,
587
+ ),
588
+ row=1,
589
+ col=2,
590
+ )
591
+
592
+ total_contribution_fig.update_traces(
593
+ textposition="inside", texttemplate="%{percent:.1%}"
594
+ )
595
+ total_contribution_fig.update_layout(
596
+ uniformtext_minsize=12, title="Channel contribution", uniformtext_mode="hide"
597
+ )
598
+ return total_contribution_fig
599
+
600
+
601
+ def create_contribuion_stacked_plot(scenario):
602
+ weekly_contribution_fig = make_subplots(
603
+ rows=1,
604
+ cols=2,
605
+ subplot_titles=["Spends", "Revenue"],
606
+ specs=[[{"type": "bar"}, {"type": "bar"}]],
607
+ )
608
+ raw_df = st.session_state["raw_df"]
609
+ df = raw_df.sort_values(by="Date")
610
+ x = df.Date
611
+ weekly_spends_data = []
612
+ weekly_sales_data = []
613
+
614
+ for i, channel_name in enumerate(st.session_state["channels_list"]):
615
+ color = color_palette[i % len(color_palette)]
616
+
617
+ weekly_spends_data.append(
618
+ go.Bar(
619
+ x=x,
620
+ y=scenario.channels[channel_name].actual_spends
621
+ * scenario.channels[channel_name].conversion_rate,
622
+ name=channel_name_formating(channel_name),
623
+ hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}",
624
+ legendgroup=channel_name,
625
+ marker_color=color,
626
+ )
627
+ )
628
+
629
+ weekly_sales_data.append(
630
+ go.Bar(
631
+ x=x,
632
+ y=scenario.channels[channel_name].actual_sales,
633
+ name=channel_name_formating(channel_name),
634
+ hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}",
635
+ legendgroup=channel_name,
636
+ showlegend=False,
637
+ marker_color=color,
638
+ )
639
+ )
640
+
641
+ for _d in weekly_spends_data:
642
+ weekly_contribution_fig.add_trace(_d, row=1, col=1)
643
+ for _d in weekly_sales_data:
644
+ weekly_contribution_fig.add_trace(_d, row=1, col=2)
645
+
646
+ weekly_contribution_fig.add_trace(
647
+ go.Bar(
648
+ x=x,
649
+ y=scenario.constant + scenario.correction,
650
+ name="Non Media",
651
+ hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}",
652
+ marker_color=color_palette[-1],
653
+ ),
654
+ row=1,
655
+ col=2,
656
+ )
657
+
658
+ weekly_contribution_fig.update_layout(
659
+ barmode="stack", title="Channel contribution by week", xaxis_title="Date"
660
+ )
661
+ weekly_contribution_fig.update_xaxes(showgrid=False)
662
+ weekly_contribution_fig.update_yaxes(showgrid=False)
663
+ return weekly_contribution_fig
664
+
665
+
666
+ def create_channel_spends_sales_plot(channel):
667
+ if channel is not None:
668
+ x = channel.dates
669
+ _spends = channel.actual_spends * channel.conversion_rate
670
+ _sales = channel.actual_sales
671
+ channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
672
+ channel_sales_spends_fig.add_trace(
673
+ go.Bar(
674
+ x=x,
675
+ y=_sales,
676
+ marker_color=color_palette[
677
+ 3
678
+ ], # You can choose a color from the palette
679
+ name="Revenue",
680
+ hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}",
681
+ ),
682
+ secondary_y=False,
683
+ )
684
+
685
+ channel_sales_spends_fig.add_trace(
686
+ go.Scatter(
687
+ x=x,
688
+ y=_spends,
689
+ line=dict(
690
+ color=color_palette[2]
691
+ ), # You can choose another color from the palette
692
+ name="Spends",
693
+ hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}",
694
+ ),
695
+ secondary_y=True,
696
+ )
697
+
698
+ channel_sales_spends_fig.update_layout(
699
+ xaxis_title="Date",
700
+ yaxis_title="Revenue",
701
+ yaxis2_title="Spends ($)",
702
+ title="Channel spends and Revenue week-wise",
703
+ )
704
+ channel_sales_spends_fig.update_xaxes(showgrid=False)
705
+ channel_sales_spends_fig.update_yaxes(showgrid=False)
706
+ else:
707
+ raw_df = st.session_state["raw_df"]
708
+ df = raw_df.sort_values(by="Date")
709
+ x = df.Date
710
+ scenario = class_from_dict(st.session_state["default_scenario_dict"])
711
+ _sales = 0 #scenario.constant + scenario.correction
712
+ channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
713
+ channel_sales_spends_fig.add_trace(
714
+ go.Bar(
715
+ x=x,
716
+ y=_sales,
717
+ marker_color=color_palette[
718
+ 0
719
+ ], # You can choose a color from the palette
720
+ name="Revenue",
721
+ hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}",
722
+ ),
723
+ secondary_y=False,
724
+ )
725
+
726
+ channel_sales_spends_fig.update_layout(
727
+ xaxis_title="Date",
728
+ yaxis_title="Revenue",
729
+ yaxis2_title="Spends ($)",
730
+ title="Channel spends and Revenue week-wise",
731
+ )
732
+ channel_sales_spends_fig.update_xaxes(showgrid=False)
733
+ channel_sales_spends_fig.update_yaxes(showgrid=False)
734
+
735
+ return channel_sales_spends_fig
736
+
737
+
738
+ def format_numbers(value, n_decimals=1, include_indicator=True):
739
+ if include_indicator:
740
+ return f"{CURRENCY_INDICATOR} {numerize(value,n_decimals)}"
741
+ else:
742
+ return f"{numerize(value,n_decimals)}"
743
+
744
+ def format_numbers_f(value, n_decimals=1, include_indicator=False):
745
+ if include_indicator:
746
+ return f"{CURRENCY_INDICATOR} {numerize(value,n_decimals)}"
747
+ else:
748
+ return f"{numerize(value,n_decimals)}"
749
+
750
+ def decimal_formater(num_string, n_decimals=1):
751
+ parts = num_string.split(".")
752
+ if len(parts) == 1:
753
+ return num_string + "." + "0" * n_decimals
754
+ else:
755
+ to_be_padded = n_decimals - len(parts[-1])
756
+ if to_be_padded > 0:
757
+ return num_string + "0" * to_be_padded
758
+ else:
759
+ return num_string
760
+
761
+
762
+ def channel_name_formating(channel_name):
763
+ name_mod = channel_name.replace("_", " ")
764
+ if name_mod.lower().endswith(" imp"):
765
+ name_mod = name_mod.replace("Imp", "Spend")
766
+ elif name_mod.lower().endswith(" clicks"):
767
+ name_mod = name_mod.replace("Clicks", "Spend")
768
+ # st.write(channel_name)
769
+ key_dict = my_dict = {
770
+ "DisplayProspecting" :"Display Prospecting",
771
+ "CableTV" :"Cable TV",
772
+ "SocialProspecting": "Social Prospecting",
773
+ "Connected&OTTTV" :"Connected & OTTTV",
774
+ "SocialRetargeting" : "Social Retargeting",
775
+ "DigitalPartners" :"Digital Partners",
776
+ "Audio" :"Audio",
777
+ "BroadcastTV": "Broadcast TV",
778
+ "SearchNon-brand": "Search Non-brand",
779
+ "Email" :"Email" ,
780
+ "SearchBrand": "Search Brand",
781
+ "DisplayRetargeting" : "Display Retargeting" ,
782
+ "\xa0Video":"Video"
783
+ }
784
+ return key_dict[channel_name]
785
+
786
+
787
+ def send_email(email, message):
788
+ s = smtplib.SMTP("smtp.gmail.com", 587)
789
+ s.starttls()
790
+ s.login("[email protected]", "jgydhpfusuremcol")
791
+ s.sendmail("[email protected]", email, message)
792
+ s.quit()
793
+
794
+
795
+ if __name__ == "__main__":
796
+ initialize_data()
utilities_with_panel.py ADDED
@@ -0,0 +1,1025 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from numerize.numerize import numerize
2
+ import streamlit as st
3
+ import pandas as pd
4
+ import json
5
+ from classes import Channel, Scenario
6
+ import numpy as np
7
+ from plotly.subplots import make_subplots
8
+ import plotly.graph_objects as go
9
+ from classes import class_to_dict
10
+ from collections import OrderedDict
11
+ import io
12
+ import plotly
13
+ from pathlib import Path
14
+ import pickle
15
+ import streamlit_authenticator as stauth
16
+ import yaml
17
+ from yaml import SafeLoader
18
+ from streamlit.components.v1 import html
19
+ import smtplib
20
+ from scipy.optimize import curve_fit
21
+ from sklearn.metrics import r2_score
22
+ from classes import class_from_dict
23
+ import os
24
+ import base64
25
+
26
+
27
+
28
+
29
+ color_palette = ['#001f78', '#00b5db', '#f03d14', '#fa6e0a', '#ffbf45']
30
+
31
+
32
+ CURRENCY_INDICATOR = '€'
33
+
34
+ def load_authenticator():
35
+ with open('config.yaml') as file:
36
+ config = yaml.load(file, Loader=SafeLoader)
37
+ st.session_state['config'] = config
38
+ authenticator = stauth.Authenticate(
39
+ config['credentials'],
40
+ config['cookie']['name'],
41
+ config['cookie']['key'],
42
+ config['cookie']['expiry_days'],
43
+ config['preauthorized']
44
+ )
45
+ st.session_state['authenticator'] = authenticator
46
+ return authenticator
47
+
48
+ def nav_page(page_name, timeout_secs=3):
49
+ nav_script = """
50
+ <script type="text/javascript">
51
+ function attempt_nav_page(page_name, start_time, timeout_secs) {
52
+ var links = window.parent.document.getElementsByTagName("a");
53
+ for (var i = 0; i < links.length; i++) {
54
+ if (links[i].href.toLowerCase().endsWith("/" + page_name.toLowerCase())) {
55
+ links[i].click();
56
+ return;
57
+ }
58
+ }
59
+ var elasped = new Date() - start_time;
60
+ if (elasped < timeout_secs * 1000) {
61
+ setTimeout(attempt_nav_page, 100, page_name, start_time, timeout_secs);
62
+ } else {
63
+ alert("Unable to navigate to page '" + page_name + "' after " + timeout_secs + " second(s).");
64
+ }
65
+ }
66
+ window.addEventListener("load", function() {
67
+ attempt_nav_page("%s", new Date(), %d);
68
+ });
69
+ </script>
70
+ """ % (page_name, timeout_secs)
71
+ html(nav_script)
72
+
73
+
74
+ # def load_local_css(file_name):
75
+ # with open(file_name) as f:
76
+ # st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
77
+
78
+
79
+ # def set_header():
80
+ # return st.markdown(f"""<div class='main-header'>
81
+ # <h1>MMM LiME</h1>
82
+ # <img src="https://assets-global.website-files.com/64c8fffb0e95cbc525815b79/64df84637f83a891c1473c51_Vector%20(Stroke).svg ">
83
+ # </div>""", unsafe_allow_html=True)
84
+
85
+ # path = os.path.dirname(__file__)
86
+
87
+ # file_ = open(f"{path}/mastercard_logo.png", "rb")
88
+
89
+ # contents = file_.read()
90
+
91
+ # data_url = base64.b64encode(contents).decode("utf-8")
92
+
93
+ # file_.close()
94
+
95
+
96
+
97
+ DATA_PATH = './data'
98
+
99
+ IMAGES_PATH = './data/images_224_224'
100
+
101
+ # New - S# # # print 2
102
+ if 'bin_dict' not in st.session_state:
103
+
104
+ with open("data_import.pkl", "rb") as f:
105
+ data = pickle.load(f)
106
+
107
+ st.session_state['bin_dict'] = data["bin_dict"]
108
+
109
+ # panel_col = [col.lower().replace('.','_').replace('@','_').replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_") for col in st.session_state['bin_dict']['Panel Level 1'] ] [0]# set the panel column
110
+
111
+ panel_col="Panel"
112
+
113
+ is_panel = True if len(panel_col)>0 else False
114
+
115
+ date_col='Date'
116
+ #is_panel = False # flag if set to true - do panel level response curves
117
+
118
+ def load_local_css(file_name):
119
+
120
+ with open(file_name) as f:
121
+
122
+ st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
123
+
124
+
125
+
126
+
127
+
128
+ # def set_header():
129
+
130
+ # return st.markdown(f"""<div class='main-header'>
131
+
132
+ # <h1>H & M Recommendations</h1>
133
+
134
+ # <img src="data:image;base64,{data_url}", alt="Logo">
135
+
136
+ # </div>""", unsafe_allow_html=True)
137
+ path1 = os.path.dirname(__file__)
138
+
139
+ file_1 = open(f"ALDI_2017.png", "rb")
140
+
141
+ contents1 = file_1.read()
142
+
143
+ data_url1 = base64.b64encode(contents1).decode("utf-8")
144
+
145
+ file_1.close()
146
+
147
+
148
+
149
+ DATA_PATH1 = './data'
150
+
151
+ IMAGES_PATH1 = './data/images_224_224'
152
+
153
+
154
+
155
+
156
+
157
+ def set_header():
158
+ return st.markdown(f"""<div class='main-header'>
159
+ <!-- <h1></h1> -->
160
+ <div >
161
+ <img class='blend-logo' src="data:image;base64,{data_url1}", alt="Logo">
162
+ </div>""", unsafe_allow_html=True)
163
+
164
+ # def set_header():
165
+ # logo_path = "./path/to/your/local/LIME_logo.png" # Replace with the actual file path
166
+ # text = "LiME"
167
+ # return st.markdown(f"""<div class='main-header'>
168
+ # <img src="data:image/png;base64,{data_url}" alt="Logo" style="float: left; margin-right: 10px; width: 100px; height: auto;">
169
+ # <h1>{text}</h1>
170
+ # </div>""", unsafe_allow_html=True)
171
+
172
+
173
+ def s_curve(x,K,b,a,x0):
174
+ return K / (1 + b * np.exp(-a*(x-x0)))
175
+
176
+
177
+ def overview_test_data_prep_panel(X, df, spends_X, date_col, panel_col, target_col):
178
+ '''
179
+ function to create the data which is used in initialize data fn
180
+ X : X test with contributions
181
+ df : originally uploaded data (media data) which has raw vars
182
+ spends_X : spends of dates in X test
183
+ '''
184
+
185
+ # define channels
186
+ channels = {'paid_search': ['paid_search_impressions', 'paid_search_clicks'],
187
+
188
+ 'fb_level_achieved_tier_1': ['fb_level_achieved_tier_1_impressions'], #, 'fb:_level_achieved_-_tier_1_clicks'],
189
+
190
+ 'fb_level_achieved_tier_2': ['fb:_level_achieved_tier_2_impressions',
191
+ 'fb_level_achieved_tier_2_clicks'],
192
+
193
+ 'paid_social_others' : ['paid_social_others_impressions', 'paid_social_others_clicks'],
194
+
195
+ 'ga_app': ['ga_app_impressions', 'ga_app_clicks'],
196
+
197
+ 'digital_tactic_others': ['digital_tactic_others_impressions', 'digital_tactic_others_clicks'],
198
+
199
+ 'kwai': ['kwai_impressions', 'kwai_clicks'],
200
+
201
+ 'programmatic': ['programmatic_impressions', 'programmatic_clicks'],
202
+
203
+ # 'affiliates':['affiliates_clicks'],
204
+ #
205
+ # "indicacao":['indicacao_clicks'],
206
+ #
207
+ # "infleux":['infleux_clicks'],
208
+ #
209
+ # "influencer":['influencer_clicks']
210
+ }
211
+
212
+ channel_list = list(channels.keys())
213
+
214
+ # map transformed variable to raw variable name & channel name
215
+ # mapping eg : paid_search_clicks_lag_2 (transformed var) --> paid_search_clicks (raw var) --> paid_search (channel)
216
+ variables = {}
217
+ channel_and_variables = {}
218
+ new_variables = {}
219
+ new_channels_and_variables = {}
220
+
221
+ for transformed_var in [col for col in
222
+ X.drop(columns=[date_col, panel_col, target_col, 'pred', 'panel_effect']).columns if
223
+ "_contr" not in col]:
224
+ if len([col for col in df.columns if col in transformed_var]) == 1:
225
+ raw_var = [col for col in df.columns if col in transformed_var][0]
226
+ variables[transformed_var] = raw_var
227
+ channel_and_variables[raw_var] = [channel for channel, raw_vars in channels.items() if raw_var in raw_vars][
228
+ 0]
229
+ else:
230
+ new_variables[transformed_var] = transformed_var
231
+ new_channels_and_variables[transformed_var] = 'base'
232
+
233
+ # Raw DF
234
+ raw_X = pd.merge(X[[date_col, panel_col]], df[[date_col, panel_col] + list(variables.values())], how='left',
235
+ on=[date_col, panel_col])
236
+ assert len(raw_X) == len(X)
237
+
238
+ raw_X_cols = []
239
+ for i in raw_X.columns:
240
+ if i in channel_and_variables.keys():
241
+ raw_X_cols.append(channel_and_variables[i])
242
+ else:
243
+ raw_X_cols.append(i)
244
+ raw_X.columns = raw_X_cols
245
+
246
+ # Contribution DF
247
+ contr_X = X[[date_col, panel_col, 'panel_effect'] + [col for col in X.columns if
248
+ "_contr" in col and "sum_" not in col]].copy()
249
+ new_variables = [col for col in contr_X.columns if
250
+ "_flag" in col.lower() or "trend" in col.lower() or "sine" in col.lower()]
251
+ if len(new_variables) > 0:
252
+ contr_X['const'] = contr_X[['panel_effect'] + new_variables].sum(axis=1)
253
+ contr_X.drop(columns=['panel_effect'], inplace=True)
254
+ contr_X.drop(columns=new_variables, inplace=True)
255
+ else:
256
+ contr_X.rename(columns={'panel_effect': 'const'}, inplace=True)
257
+
258
+ new_contr_X_cols = []
259
+ for col in contr_X.columns:
260
+ col_clean = col.replace("_contr", "")
261
+ new_contr_X_cols.append(col_clean)
262
+ contr_X.columns = new_contr_X_cols
263
+
264
+ contr_X_cols = []
265
+ for i in contr_X.columns:
266
+ if i in variables.keys():
267
+ contr_X_cols.append(channel_and_variables[variables[i]])
268
+ else:
269
+ contr_X_cols.append(i)
270
+ contr_X.columns = contr_X_cols
271
+
272
+ # Spends DF
273
+ spends_X.columns = [col.replace("_cost", "") for col in spends_X.columns]
274
+
275
+ raw_X.rename(columns={"date": "Date"}, inplace=True)
276
+ contr_X.rename(columns={"date": "Date"}, inplace=True)
277
+ spends_X.rename(columns={'date': 'Week'}, inplace=True)
278
+
279
+ # Create excel
280
+ file_name = "data_test_overview_panel_#" + target_col + ".xlsx"
281
+ with pd.ExcelWriter(file_name) as writer:
282
+ raw_X.to_excel(writer, sheet_name="RAW DATA MMM", index=False)
283
+ contr_X.to_excel(writer, sheet_name="CONTRIBUTION MMM", index=False)
284
+ spends_X.to_excel(writer, sheet_name="SPEND INPUT", index=False)
285
+
286
+
287
+ def overview_test_data_prep_nonpanel(X, df, spends_X, date_col, target_col):
288
+ '''
289
+ function to create the data which is used in initialize data fn
290
+ X : X test with contributions
291
+ df : originally uploaded data (media data) which has raw vars
292
+ spends_X : spends of dates in X test
293
+ '''
294
+ # define channels
295
+ channels = {'paid_search': ['paid_search_impressions', 'paid_search_clicks'],
296
+
297
+ 'fb_level_achieved_tier_1': ['fb_level_achieved_tier_1_impressions', 'fb_level_achieved_tier_1_clicks'],
298
+
299
+ 'fb_level_achieved_tier_2': ['fb_level_achieved_tier_2_impressions',
300
+ 'fb_level_achieved_tier_2_clicks'],
301
+
302
+ 'paid_social_others' : ['paid_social_others_impressions', 'paid_social_others_clicks'],
303
+
304
+ 'ga_app_will_and_cid_pequena_baixo_risco': ['ga_app_will_and_cid_pequena_baixo_risco_impressions', 'ga_app_will_and_cid_pequena_baixo_risco_clicks'],
305
+
306
+ 'digital_tactic_others': ['digital_tactic_others_impressions', 'digital_tactic_others_clicks'],
307
+
308
+ 'kwai': ['kwai_impressions', 'kwai_clicks'],
309
+
310
+ 'programmatic': ['programmatic_impressions', 'programmatic_clicks'],
311
+
312
+ 'affiliates':['affiliates_clicks', 'affiliates_impressions'],
313
+
314
+ "indicacao":['indicacao_clicks', 'indicacao_impressions'],
315
+
316
+ "infleux":['infleux_clicks', 'infleux_impressions'],
317
+
318
+ "influencer":['influencer_clicks', 'influencer_impressions']
319
+ }
320
+
321
+ channel_list = list(channels.keys())
322
+
323
+ # map transformed variable to raw variable name & channel name
324
+ # mapping eg : paid_search_clicks_lag_2 (transformed var) --> paid_search_clicks (raw var) --> paid_search (channel)
325
+ variables = {}
326
+ channel_and_variables = {}
327
+ new_variables = {}
328
+ new_channels_and_variables = {}
329
+
330
+ cols_to_del = list(set([date_col, target_col, 'pred']).intersection((set(X.columns))))
331
+ for transformed_var in [col for col in
332
+ X.drop(columns=cols_to_del).columns if
333
+ "_contr" not in col]: # also has 'const'
334
+ if len([col for col in df.columns if col in transformed_var]) == 1: # col is raw var
335
+ raw_var = [col for col in df.columns if col in transformed_var][0]
336
+ variables[transformed_var] = raw_var
337
+ channel_and_variables[raw_var] = [channel for channel, raw_vars in channels.items() if raw_var in raw_vars][0]
338
+ else: # when no corresponding raw var then base
339
+ new_variables[transformed_var] = transformed_var
340
+ new_channels_and_variables[transformed_var] = 'base'
341
+
342
+ # Raw DF
343
+ raw_X = pd.merge(X[[date_col]], df[[date_col] + list(variables.values())], how='left',
344
+ on=[date_col])
345
+ assert len(raw_X) == len(X)
346
+
347
+ raw_X_cols = []
348
+ for i in raw_X.columns:
349
+ if i in channel_and_variables.keys():
350
+ raw_X_cols.append(channel_and_variables[i])
351
+ else:
352
+ raw_X_cols.append(i)
353
+ raw_X.columns = raw_X_cols
354
+
355
+ # Contribution DF
356
+ contr_X = X[[date_col] + [col for col in X.columns if "_contr" in col and "sum_" not in col]].copy()
357
+ # st.write(contr_X.columns)
358
+ new_variables = [col for col in contr_X.columns if
359
+ "_flag" in col.lower() or "trend" in col.lower() or "sine" in col.lower()]
360
+ if len(new_variables) > 0: # if new vars are available, their contributions should be added to base (called const)
361
+ contr_X['const_contr'] = contr_X[['const_contr'] + new_variables].sum(axis=1)
362
+ contr_X.drop(columns=new_variables, inplace=True)
363
+
364
+
365
+ new_contr_X_cols = []
366
+ for col in contr_X.columns:
367
+ col_clean = col.replace("_contr", "")
368
+ new_contr_X_cols.append(col_clean)
369
+ contr_X.columns = new_contr_X_cols
370
+
371
+ contr_X_cols = []
372
+ for i in contr_X.columns:
373
+ if i in variables.keys():
374
+ contr_X_cols.append(channel_and_variables[variables[i]])
375
+ else:
376
+ contr_X_cols.append(i)
377
+ contr_X.columns = contr_X_cols
378
+
379
+ # Spends DF
380
+ spends_X.columns = [col.replace("_cost", "").replace("_spends", '').replace("_spend", "") for col in spends_X.columns]
381
+
382
+ raw_X.rename(columns={"date": "Date"}, inplace=True)
383
+ contr_X.rename(columns={"date": "Date"}, inplace=True)
384
+ spends_X.rename(columns={'date': 'Week'}, inplace=True)
385
+
386
+ # Create excel
387
+ file_name = "data_test_overview_panel_#" + target_col + ".xlsx"
388
+ with pd.ExcelWriter(file_name) as writer:
389
+ raw_X.to_excel(writer, sheet_name="RAW DATA MMM", index=False)
390
+ contr_X.to_excel(writer, sheet_name="CONTRIBUTION MMM", index=False)
391
+ spends_X.to_excel(writer, sheet_name="SPEND INPUT", index=False)
392
+
393
+
394
+ def initialize_data(target_col,selected_markets):
395
+ # uopx_conv_rates = {'streaming_impressions' : 0.007,'digital_impressions' : 0.007,'search_clicks' : 0.00719,'tv_impressions' : 0.000173,
396
+ # "digital_clicks":0.005,"streaming_clicks":0.004,'streaming_spends':1,"tv_spends":1,"search_spends":1,
397
+ # "digital_spends":1}
398
+ ## # # print('State initialized')
399
+ # excel = pd.read_excel("data_test_overview_panel.xlsx",sheet_name=None)
400
+ #excel = pd.read_excel("Overview_data_test_panel@#revenue.xlsx" + target_col + ".xlsx",sheet_name=None)
401
+
402
+ excel = pd.read_excel("Overview_data_test_panel@#prospects.xlsx",sheet_name=None)
403
+
404
+ raw_df = excel['RAW DATA MMM']
405
+
406
+ spend_df = excel['SPEND INPUT']
407
+ contri_df = excel['CONTRIBUTION MMM']
408
+
409
+ #st.write(raw_df)
410
+ if selected_markets!= "Total Market":
411
+
412
+ raw_df=raw_df[raw_df['Panel']==selected_markets]
413
+ spend_df=spend_df[spend_df['Panel']==selected_markets]
414
+ contri_df=contri_df[contri_df['Panel']==selected_markets]
415
+
416
+ else:
417
+ raw_df=raw_df.groupby('Date').sum().reset_index()
418
+ spend_df=spend_df.groupby('Week').sum().reset_index()
419
+ contri_df=contri_df.groupby('Date').sum().reset_index()
420
+ #Revenue_df = excel['Revenue']
421
+
422
+ ## remove sesonalities, indices etc ...
423
+ exclude_columns = ['Date', 'Week','Panel',date_col, panel_col,'Others'
424
+ ]
425
+
426
+ # Aggregate all 3 dfs to date level (from date-panel level)
427
+ raw_df[date_col]=pd.to_datetime(raw_df[date_col])
428
+ raw_df_aggregations = {c:'sum' for c in raw_df.columns if c not in exclude_columns}
429
+ raw_df = raw_df.groupby(date_col).agg(raw_df_aggregations).reset_index()
430
+
431
+ contri_df[date_col]=pd.to_datetime(contri_df[date_col])
432
+ contri_df_aggregations = {c:'sum' for c in contri_df.columns if c not in exclude_columns}
433
+ contri_df = contri_df.groupby(date_col).agg(contri_df_aggregations).reset_index()
434
+
435
+ input_df = raw_df.sort_values(by=[date_col])
436
+
437
+ output_df = contri_df.sort_values(by=[date_col])
438
+
439
+ spend_df['Week'] = pd.to_datetime(spend_df['Week'], format='%Y-%m-%d', errors='coerce')
440
+ spend_df_aggregations = {c: 'sum' for c in spend_df.columns if c not in exclude_columns}
441
+ spend_df = spend_df.groupby('Week').agg(spend_df_aggregations).reset_index()
442
+ # spend_df['Week'] = pd.to_datetime(spend_df['Week'], errors='coerce')
443
+ # spend_df = spend_df.sort_values(by='Week')
444
+
445
+
446
+ channel_list = [col for col in input_df.columns if col not in exclude_columns]
447
+
448
+ response_curves = {}
449
+ mapes = {}
450
+ rmses = {}
451
+ upper_limits = {}
452
+ powers = {}
453
+ r2 = {}
454
+ conv_rates = {}
455
+ output_cols = []
456
+ channels = {}
457
+ sales = None
458
+ dates = input_df.Date.values
459
+ actual_output_dic = {}
460
+ actual_input_dic = {}
461
+
462
+ # ONLY FOR TESTING
463
+ # channel_list=['programmatic']
464
+ infeasible_channels = [c for c in contri_df.select_dtypes(include=['float', 'int']).columns if contri_df[c].sum()<=0]
465
+ # st.write(infeasible_channels)
466
+ channel_list=list(set(channel_list)-set(infeasible_channels))
467
+
468
+
469
+ for inp_col in channel_list:
470
+ #st.write(inp_col)
471
+
472
+ # # New - S# # # print 2
473
+ # if is_panel:
474
+ # input_df1 = input_df.groupby([date_col]).agg({inp_col:'sum'}).reset_index() # aggregate spends on date
475
+ # spends = input_df1[inp_col].values
476
+ # else :
477
+ # spends = input_df[inp_col].values
478
+ spends = spend_df[inp_col].values
479
+
480
+ x = spends.copy()
481
+ # upper limit for penalty
482
+ upper_limits[inp_col] = 2*x.max()
483
+
484
+
485
+
486
+ # contribution
487
+ # New - S# # # print 2
488
+ out_col = [_col for _col in output_df.columns if _col.startswith(inp_col)][0]
489
+ if is_panel :
490
+ output_df1 = output_df.groupby([date_col]).agg({out_col:'sum'}).reset_index()
491
+ y = output_df1[out_col].values.copy()
492
+ else :
493
+ y = output_df[out_col].values.copy()
494
+
495
+ actual_output_dic[inp_col] = y.copy()
496
+ actual_input_dic[inp_col] = x.copy()
497
+ ##output cols aggregation
498
+ output_cols.append(out_col)
499
+
500
+ ## scale the input
501
+ power = (np.ceil(np.log(x.max()) / np.log(10) )- 3)
502
+ if power >= 0 :
503
+ x = x / 10**power
504
+
505
+
506
+ x = x.astype('float64')
507
+ y = y.astype('float64')
508
+ ## # # print('## # # printing yyyyyyyyy')
509
+ ## # # print(inp_col)
510
+ ## # # print(x.max())
511
+ ## # # print(y.max())
512
+ # st.write(y.max(),x.max())
513
+ # # # print(y.max(),x.max())
514
+ if y.max()<=0.01:
515
+ if x.max()<=0.01 :
516
+ st.write("here-here")
517
+ bounds = ((0, 0, 0, 0), (3 * 0.01, 1000, 1, 0.01))
518
+
519
+ else :
520
+ st.write("here")
521
+ bounds = ((0, 0, 0, 0), (3 * 0.01, 1000, 1, 0.01))
522
+ else :
523
+ bounds = ((0, 0, 0, 0), (3 * y.max(), 1000, 1, x.max()))
524
+ #bounds = ((y.max(), 3*y.max()),(0,1000),(0,1),(0,x.max()))
525
+ params,_ = curve_fit(s_curve,x,y,p0=(2*y.max(),0.01,1e-5,x.max()),
526
+ bounds=bounds,
527
+ maxfev=int(1e5))
528
+ mape = (100 * abs(1 - s_curve(x, *params) / y.clip(min=1))).mean()
529
+ rmse = np.sqrt(((y - s_curve(x,*params))**2).mean())
530
+ r2_ = r2_score(y, s_curve(x,*params))
531
+
532
+ response_curves[inp_col] = {'K' : params[0], 'b' : params[1], 'a' : params[2], 'x0' : params[3]}
533
+ mapes[inp_col] = mape
534
+ rmses[inp_col] = rmse
535
+ r2[inp_col] = r2_
536
+ powers[inp_col] = power
537
+
538
+
539
+ ## conversion rates
540
+ spend_col = [_col for _col in spend_df.columns if _col.startswith(inp_col.rsplit('_',1)[0])][0]
541
+
542
+ ## # # print('## # # printing spendssss')
543
+ ## # # print(spend_col)
544
+ conv = (spend_df.set_index('Week')[spend_col] / input_df.set_index('Date')[inp_col].clip(lower=1)).reset_index()
545
+ conv.rename(columns={'index':'Week'},inplace=True)
546
+ conv['year'] = conv.Week.dt.year
547
+ conv_rates[inp_col] = list(conv.drop('Week',axis=1).mean().to_dict().values())[0]
548
+ ### # # print('Before',conv_rates[inp_col])
549
+ # conv_rates[inp_col] = uopx_conv_rates[inp_col]
550
+ ### # # print('After',(conv_rates[inp_col]))
551
+
552
+
553
+ channel = Channel(name=inp_col,dates=dates,
554
+ spends=spends,
555
+ # conversion_rate = np.mean(list(conv_rates[inp_col].values())),
556
+ conversion_rate = conv_rates[inp_col],
557
+ response_curve_type='s-curve',
558
+ response_curve_params={'K' : params[0], 'b' : params[1], 'a' : params[2], 'x0' : params[3]},
559
+ bounds=np.array([-10,10]))
560
+ channels[inp_col] = channel
561
+ if sales is None:
562
+ sales = channel.actual_sales
563
+ else:
564
+ sales += channel.actual_sales
565
+ # st.write(inp_col, channel.actual_sales)
566
+ # st.write(output_cols)
567
+ other_contributions = output_df.drop([*output_cols], axis=1).sum(axis=1, numeric_only = True).values
568
+ correction = output_df.drop(['Date'],axis=1).sum(axis=1).values - (sales + other_contributions)
569
+
570
+ scenario_test_df=pd.DataFrame(columns=['other_contributions','correction', 'sales'])
571
+ scenario_test_df['other_contributions']=other_contributions
572
+ scenario_test_df['correction']=correction
573
+ scenario_test_df['sales']=sales
574
+ scenario_test_df.to_csv("test/scenario_test_df.csv",index=False)
575
+ output_df.to_csv("test/output_df.csv",index=False)
576
+
577
+ scenario = Scenario(name='default', channels=channels, constant=other_contributions, correction = correction)
578
+ ## setting session variables
579
+ st.session_state['initialized'] = True
580
+ st.session_state['actual_df'] = input_df
581
+ st.session_state['raw_df'] = raw_df
582
+ st.session_state['contri_df'] = output_df
583
+ default_scenario_dict = class_to_dict(scenario)
584
+ st.session_state['default_scenario_dict'] = default_scenario_dict
585
+ st.session_state['scenario'] = scenario
586
+ st.session_state['channels_list'] = channel_list
587
+ st.session_state['optimization_channels'] = {channel_name : False for channel_name in channel_list}
588
+ st.session_state['rcs'] = response_curves
589
+ st.session_state['powers'] = powers
590
+ st.session_state['actual_contribution_df'] = pd.DataFrame(actual_output_dic)
591
+ st.session_state['actual_input_df'] = pd.DataFrame(actual_input_dic)
592
+
593
+ for channel in channels.values():
594
+ st.session_state[channel.name] = numerize(channel.actual_total_spends * channel.conversion_rate,1)
595
+
596
+ st.session_state['xlsx_buffer'] = io.BytesIO()
597
+
598
+
599
+ if Path('../saved_scenarios.pkl').exists():
600
+ with open('../saved_scenarios.pkl','rb') as f:
601
+ st.session_state['saved_scenarios'] = pickle.load(f)
602
+ else:
603
+ st.session_state['saved_scenarios'] = OrderedDict()
604
+
605
+ st.session_state['total_spends_change'] = 0
606
+ st.session_state['optimization_channels'] = {channel_name : False for channel_name in channel_list}
607
+ st.session_state['disable_download_button'] = True
608
+
609
+ # def initialize_data():
610
+ # # fetch data from excel
611
+ # output = pd.read_excel('data.xlsx',sheet_name=None)
612
+ # raw_df = output['RAW DATA MMM']
613
+ # contribution_df = output['CONTRIBUTION MMM']
614
+ # Revenue_df = output['Revenue']
615
+
616
+ # ## channels to be shows
617
+ # channel_list = []
618
+ # for col in raw_df.columns:
619
+ # if 'click' in col.lower() or 'spend' in col.lower() or 'imp' in col.lower():
620
+ # ### # # print(col)
621
+ # channel_list.append(col)
622
+ # else:
623
+ # pass
624
+
625
+ # ## NOTE : Considered only Desktop spends for all calculations
626
+ # acutal_df = raw_df[raw_df.Region == 'Desktop'].copy()
627
+ # ## NOTE : Considered one year of data
628
+ # acutal_df = acutal_df[acutal_df.Date>'2020-12-31']
629
+ # actual_df = acutal_df.drop('Region',axis=1).sort_values(by='Date')[[*channel_list,'Date']]
630
+
631
+ # ##load response curves
632
+ # with open('./grammarly_response_curves.json','r') as f:
633
+ # response_curves = json.load(f)
634
+
635
+ # ## create channel dict for scenario creation
636
+ # dates = actual_df.Date.values
637
+ # channels = {}
638
+ # rcs = {}
639
+ # constant = 0.
640
+ # for i,info_dict in enumerate(response_curves):
641
+ # name = info_dict.get('name')
642
+ # response_curve_type = info_dict.get('response_curve')
643
+ # response_curve_params = info_dict.get('params')
644
+ # rcs[name] = response_curve_params
645
+ # if name != 'constant':
646
+ # spends = actual_df[name].values
647
+ # channel = Channel(name=name,dates=dates,
648
+ # spends=spends,
649
+ # response_curve_type=response_curve_type,
650
+ # response_curve_params=response_curve_params,
651
+ # bounds=np.array([-30,30]))
652
+
653
+ # channels[name] = channel
654
+ # else:
655
+ # constant = info_dict.get('value',0.) * len(dates)
656
+
657
+ # ## create scenario
658
+ # scenario = Scenario(name='default', channels=channels, constant=constant)
659
+ # default_scenario_dict = class_to_dict(scenario)
660
+
661
+
662
+ # ## setting session variables
663
+ # st.session_state['initialized'] = True
664
+ # st.session_state['actual_df'] = actual_df
665
+ # st.session_state['raw_df'] = raw_df
666
+ # st.session_state['default_scenario_dict'] = default_scenario_dict
667
+ # st.session_state['scenario'] = scenario
668
+ # st.session_state['channels_list'] = channel_list
669
+ # st.session_state['optimization_channels'] = {channel_name : False for channel_name in channel_list}
670
+ # st.session_state['rcs'] = rcs
671
+ # for channel in channels.values():
672
+ # if channel.name not in st.session_state:
673
+ # st.session_state[channel.name] = float(channel.actual_total_spends)
674
+
675
+ # if 'xlsx_buffer' not in st.session_state:
676
+ # st.session_state['xlsx_buffer'] = io.BytesIO()
677
+
678
+ # ## for saving scenarios
679
+ # if 'saved_scenarios' not in st.session_state:
680
+ # if Path('../saved_scenarios.pkl').exists():
681
+ # with open('../saved_scenarios.pkl','rb') as f:
682
+ # st.session_state['saved_scenarios'] = pickle.load(f)
683
+
684
+ # else:
685
+ # st.session_state['saved_scenarios'] = OrderedDict()
686
+
687
+ # if 'total_spends_change' not in st.session_state:
688
+ # st.session_state['total_spends_change'] = 0
689
+
690
+ # if 'optimization_channels' not in st.session_state:
691
+ # st.session_state['optimization_channels'] = {channel_name : False for channel_name in channel_list}
692
+
693
+ # if 'disable_download_button' not in st.session_state:
694
+ # st.session_state['disable_download_button'] = True
695
+ def create_channel_summary(scenario):
696
+ summary_columns = []
697
+
698
+ actual_spends_rows = []
699
+
700
+ actual_sales_rows = []
701
+
702
+ actual_roi_rows = []
703
+
704
+ for channel in scenario.channels.values():
705
+
706
+ name_mod = channel.name.replace('_', ' ')
707
+
708
+ if name_mod.lower().endswith(' imp'):
709
+ name_mod = name_mod.replace('Imp', ' Impressions')
710
+
711
+ # # # print(name_mod, channel.actual_total_spends, channel.conversion_rate,
712
+ channel.actual_total_spends * channel.conversion_rate
713
+
714
+ summary_columns.append(name_mod)
715
+
716
+ actual_spends_rows.append(format_numbers(float(channel.actual_total_spends * channel.conversion_rate)))
717
+
718
+ actual_sales_rows.append(format_numbers((float(channel.actual_total_sales))))
719
+
720
+ actual_roi_rows.append(decimal_formater(
721
+ format_numbers((channel.actual_total_sales) / (channel.actual_total_spends * channel.conversion_rate),
722
+ include_indicator=False, n_decimals=4), n_decimals=4))
723
+
724
+ actual_summary_df = pd.DataFrame([summary_columns, actual_spends_rows, actual_sales_rows, actual_roi_rows]).T
725
+
726
+ actual_summary_df.columns = ['Channel', 'Spends', 'Prospects', 'ROI']
727
+
728
+ actual_summary_df['Prospects'] = actual_summary_df['Prospects'].map(lambda x: str(x)[1:])
729
+
730
+ return actual_summary_df
731
+
732
+
733
+ # def create_channel_summary(scenario):
734
+ #
735
+ # # Provided data
736
+ # data = {
737
+ # 'Channel': ['Paid Search', 'Ga will cid baixo risco', 'Digital tactic others', 'Fb la tier 1', 'Fb la tier 2', 'Paid social others', 'Programmatic', 'Kwai', 'Indicacao', 'Infleux', 'Influencer'],
738
+ # 'Spends': ['$ 11.3K', '$ 155.2K', '$ 50.7K', '$ 125.4K', '$ 125.2K', '$ 105K', '$ 3.3M', '$ 47.5K', '$ 55.9K', '$ 632.3K', '$ 48.3K'],
739
+ # 'Revenue': ['558.0K', '3.5M', '5.2M', '3.1M', '3.1M', '2.1M', '20.8M', '1.6M', '728.4K', '22.9M', '4.8M']
740
+ # }
741
+ #
742
+ # # Create DataFrame
743
+ # df = pd.DataFrame(data)
744
+ #
745
+ # # Convert currency strings to numeric values
746
+ # df['Spends'] = df['Spends'].replace({'\$': '', 'K': '*1e3', 'M': '*1e6'}, regex=True).map(pd.eval).astype(int)
747
+ # df['Revenue'] = df['Revenue'].replace({'\$': '', 'K': '*1e3', 'M': '*1e6'}, regex=True).map(pd.eval).astype(int)
748
+ #
749
+ # # Calculate ROI
750
+ # df['ROI'] = ((df['Revenue'] - df['Spends']) / df['Spends'])
751
+ #
752
+ # # Format columns
753
+ # format_currency = lambda x: f"${x:,.1f}"
754
+ # format_roi = lambda x: f"{x:.1f}"
755
+ #
756
+ # df['Spends'] = ['$ 11.3K', '$ 155.2K', '$ 50.7K', '$ 125.4K', '$ 125.2K', '$ 105K', '$ 3.3M', '$ 47.5K', '$ 55.9K', '$ 632.3K', '$ 48.3K']
757
+ # df['Revenue'] = ['$ 536.3K', '$ 3.4M', '$ 5M', '$ 3M', '$ 3M', '$ 2M', '$ 20M', '$ 1.5M', '$ 7.1M', '$ 22M', '$ 4.6M']
758
+ # df['ROI'] = df['ROI'].apply(format_roi)
759
+ #
760
+ # return df
761
+
762
+
763
+ #@st.cache_data()
764
+ def create_contribution_pie(scenario):
765
+ #c1f7dc
766
+
767
+ light_blue = 'rgba(0, 31, 120, 0.7)'
768
+ light_orange = 'rgba(0, 181, 219, 0.7)'
769
+ light_green = 'rgba(240, 61, 20, 0.7)'
770
+ light_red = 'rgba(250, 110, 10, 0.7)'
771
+ light_purple = 'rgba(255, 191, 69, 0.7)'
772
+
773
+ colors_map = {col:color for col,color in zip(st.session_state['channels_list'],plotly.colors.n_colors(plotly.colors.hex_to_rgb('#BE6468'), plotly.colors.hex_to_rgb('#E7B8B7'),23))}
774
+ total_contribution_fig = make_subplots(rows=1, cols=2,subplot_titles=['Media Spends','Prospects Contribution'],specs=[[{"type": "pie"}, {"type": "pie"}]])
775
+ total_contribution_fig.add_trace(
776
+ go.Pie(labels=[channel_name_formating(channel_name) for channel_name in st.session_state['channels_list']] + ['Non Media'],
777
+ values= [round(scenario.channels[channel_name].actual_total_spends * scenario.channels[channel_name].conversion_rate,1) for channel_name in st.session_state['channels_list']] + [0],
778
+ marker_colors=[light_blue, light_orange, light_green, light_red, light_purple],
779
+ hole=0.3),
780
+ row=1, col=1)
781
+
782
+ total_contribution_fig.add_trace(
783
+ go.Pie(labels=[channel_name_formating(channel_name) for channel_name in st.session_state['channels_list']] + ['Non Media'],
784
+ values= [scenario.channels[channel_name].actual_total_sales for channel_name in st.session_state['channels_list']] + [scenario.correction.sum() + scenario.constant.sum()],
785
+ hole=0.3),
786
+ row=1, col=2)
787
+
788
+ total_contribution_fig.update_traces(textposition='inside',texttemplate='%{percent:.1%}')
789
+ total_contribution_fig.update_layout(uniformtext_minsize=12,title='', uniformtext_mode='hide')
790
+ return total_contribution_fig
791
+
792
+ #@st.cache_data()
793
+
794
+ # def create_contribuion_stacked_plot(scenario):
795
+ # weekly_contribution_fig = make_subplots(rows=1, cols=2,subplot_titles=['Spends','Revenue'],specs=[[{"type": "bar"}, {"type": "bar"}]])
796
+ # raw_df = st.session_state['raw_df']
797
+ # df = raw_df.sort_values(by='Date')
798
+ # x = df.Date
799
+ # weekly_spends_data = []
800
+ # weekly_sales_data = []
801
+ # for channel_name in st.session_state['channels_list']:
802
+ # weekly_spends_data.append((go.Bar(x=x,
803
+ # y=scenario.channels[channel_name].actual_spends * scenario.channels[channel_name].conversion_rate,
804
+ # name=channel_name_formating(channel_name),
805
+ # hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}",
806
+ # legendgroup=channel_name)))
807
+ # weekly_sales_data.append((go.Bar(x=x,
808
+ # y=scenario.channels[channel_name].actual_sales,
809
+ # name=channel_name_formating(channel_name),
810
+ # hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}",
811
+ # legendgroup=channel_name, showlegend=False)))
812
+ # for _d in weekly_spends_data:
813
+ # weekly_contribution_fig.add_trace(_d, row=1, col=1)
814
+ # for _d in weekly_sales_data:
815
+ # weekly_contribution_fig.add_trace(_d, row=1, col=2)
816
+ # weekly_contribution_fig.add_trace(go.Bar(x=x,
817
+ # y=scenario.constant + scenario.correction,
818
+ # name='Non Media',
819
+ # hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}"), row=1, col=2)
820
+ # weekly_contribution_fig.update_layout(barmode='stack', title='Channel contribuion by week', xaxis_title='Date')
821
+ # weekly_contribution_fig.update_xaxes(showgrid=False)
822
+ # weekly_contribution_fig.update_yaxes(showgrid=False)
823
+ # return weekly_contribution_fig
824
+
825
+ # @st.cache_data(allow_output_mutation=True)
826
+ # def create_channel_spends_sales_plot(channel):
827
+ # if channel is not None:
828
+ # x = channel.dates
829
+ # _spends = channel.actual_spends * channel.conversion_rate
830
+ # _sales = channel.actual_sales
831
+ # channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
832
+ # channel_sales_spends_fig.add_trace(go.Bar(x=x, y=_sales,marker_color='#c1f7dc',name='Revenue', hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}"), secondary_y = False)
833
+ # channel_sales_spends_fig.add_trace(go.Scatter(x=x, y=_spends,line=dict(color='#005b96'),name='Spends',hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}"), secondary_y = True)
834
+ # channel_sales_spends_fig.update_layout(xaxis_title='Date',yaxis_title='Revenue',yaxis2_title='Spends ($)',title='Channel spends and Revenue week wise')
835
+ # channel_sales_spends_fig.update_xaxes(showgrid=False)
836
+ # channel_sales_spends_fig.update_yaxes(showgrid=False)
837
+ # else:
838
+ # raw_df = st.session_state['raw_df']
839
+ # df = raw_df.sort_values(by='Date')
840
+ # x = df.Date
841
+ # scenario = class_from_dict(st.session_state['default_scenario_dict'])
842
+ # _sales = scenario.constant + scenario.correction
843
+ # channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
844
+ # channel_sales_spends_fig.add_trace(go.Bar(x=x, y=_sales,marker_color='#c1f7dc',name='Revenue', hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}"), secondary_y = False)
845
+ # # channel_sales_spends_fig.add_trace(go.Scatter(x=x, y=_spends,line=dict(color='#15C39A'),name='Spends',hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}"), secondary_y = True)
846
+ # channel_sales_spends_fig.update_layout(xaxis_title='Date',yaxis_title='Revenue',yaxis2_title='Spends ($)',title='Channel spends and Revenue week wise')
847
+ # channel_sales_spends_fig.update_xaxes(showgrid=False)
848
+ # channel_sales_spends_fig.update_yaxes(showgrid=False)
849
+ # return channel_sales_spends_fig
850
+
851
+
852
+ # Define a shared color palette
853
+
854
+
855
+ # def create_contribution_pie():
856
+ # color_palette = ['#F3F3F0', '#5E7D7E', '#2FA1FF', '#00EDED', '#00EAE4', '#304550', '#EDEBEB', '#7FBEFD', '#003059', '#A2F3F3', '#E1D6E2', '#B6B6B6']
857
+ # total_contribution_fig = make_subplots(rows=1, cols=2, subplot_titles=['Spends', 'Revenue'], specs=[[{"type": "pie"}, {"type": "pie"}]])
858
+ #
859
+ # channels_list = ['Paid Search', 'Ga will cid baixo risco', 'Digital tactic others', 'Fb la tier 1', 'Fb la tier 2', 'Paid social others', 'Programmatic', 'Kwai', 'Indicacao', 'Infleux', 'Influencer', 'Non Media']
860
+ #
861
+ # # Assign colors from the limited palette to channels
862
+ # colors_map = {col: color_palette[i % len(color_palette)] for i, col in enumerate(channels_list)}
863
+ # colors_map['Non Media'] = color_palette[5] # Assign fixed green color for 'Non Media'
864
+ #
865
+ # # Hardcoded values for Spends and Revenue
866
+ # spends_values = [0.5, 3.36, 1.1, 2.7, 2.7, 2.27, 70.6, 1, 1, 13.7, 1, 0]
867
+ # revenue_values = [1, 4, 5, 3, 3, 2, 50.8, 1.5, 0.7, 13, 0, 16]
868
+ #
869
+ # # Add trace for Spends pie chart
870
+ # total_contribution_fig.add_trace(
871
+ # go.Pie(
872
+ # labels=[channel_name for channel_name in channels_list],
873
+ # values=spends_values,
874
+ # marker=dict(colors=[colors_map[channel_name] for channel_name in channels_list]),
875
+ # hole=0.3
876
+ # ),
877
+ # row=1, col=1
878
+ # )
879
+ #
880
+ # # Add trace for Revenue pie chart
881
+ # total_contribution_fig.add_trace(
882
+ # go.Pie(
883
+ # labels=[channel_name for channel_name in channels_list],
884
+ # values=revenue_values,
885
+ # marker=dict(colors=[colors_map[channel_name] for channel_name in channels_list]),
886
+ # hole=0.3
887
+ # ),
888
+ # row=1, col=2
889
+ # )
890
+ #
891
+ # total_contribution_fig.update_traces(textposition='inside', texttemplate='%{percent:.1%}')
892
+ # total_contribution_fig.update_layout(uniformtext_minsize=12, title='Channel contribution', uniformtext_mode='hide')
893
+ # return total_contribution_fig
894
+
895
+ def create_contribuion_stacked_plot(scenario):
896
+ weekly_contribution_fig = make_subplots(rows=1, cols=2, subplot_titles=['Spends', 'Prospects'], specs=[[{"type": "bar"}, {"type": "bar"}]])
897
+ raw_df = st.session_state['raw_df']
898
+ df = raw_df.sort_values(by='Date')
899
+ x = df.Date
900
+ weekly_spends_data = []
901
+ weekly_sales_data = []
902
+
903
+ for i, channel_name in enumerate(st.session_state['channels_list']):
904
+ color = color_palette[i % len(color_palette)]
905
+
906
+ weekly_spends_data.append(go.Bar(
907
+ x=x,
908
+ y=scenario.channels[channel_name].actual_spends * scenario.channels[channel_name].conversion_rate,
909
+ name=channel_name_formating(channel_name),
910
+ hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}",
911
+ legendgroup=channel_name,
912
+ marker_color=color,
913
+ ))
914
+
915
+ weekly_sales_data.append(go.Bar(
916
+ x=x,
917
+ y=scenario.channels[channel_name].actual_sales,
918
+ name=channel_name_formating(channel_name),
919
+ hovertemplate="Date:%{x}<br>Prospects:%{y:$.2s}",
920
+ legendgroup=channel_name,
921
+ showlegend=False,
922
+ marker_color=color,
923
+ ))
924
+
925
+ for _d in weekly_spends_data:
926
+ weekly_contribution_fig.add_trace(_d, row=1, col=1)
927
+ for _d in weekly_sales_data:
928
+ weekly_contribution_fig.add_trace(_d, row=1, col=2)
929
+
930
+ weekly_contribution_fig.add_trace(go.Bar(
931
+ x=x,
932
+ y=scenario.constant + scenario.correction,
933
+ name='Non Media',
934
+ hovertemplate="Date:%{x}<br>Prospects:%{y:$.2s}",
935
+ marker_color=color_palette[-1],
936
+ ), row=1, col=2)
937
+
938
+ weekly_contribution_fig.update_layout(barmode='stack', title='Channel contribution by week', xaxis_title='Date')
939
+ weekly_contribution_fig.update_xaxes(showgrid=False)
940
+ weekly_contribution_fig.update_yaxes(showgrid=False)
941
+ return weekly_contribution_fig
942
+
943
+ def create_channel_spends_sales_plot(channel):
944
+ if channel is not None:
945
+ x = channel.dates
946
+ _spends = channel.actual_spends * channel.conversion_rate
947
+ _sales = channel.actual_sales
948
+ channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
949
+ channel_sales_spends_fig.add_trace(go.Bar(
950
+ x=x,
951
+ y=_sales,
952
+ marker_color=color_palette[1], # You can choose a color from the palette
953
+ name='Prospects',
954
+ hovertemplate="Date:%{x}<br>Prospects:%{y:$.2s}",
955
+ ), secondary_y=False)
956
+
957
+ channel_sales_spends_fig.add_trace(go.Scatter(
958
+ x=x,
959
+ y=_spends,
960
+ line=dict(color=color_palette[3]), # You can choose another color from the palette
961
+ name='Spends',
962
+ hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}",
963
+ ), secondary_y=True)
964
+
965
+ channel_sales_spends_fig.update_layout(xaxis_title='Date', yaxis_title='Prospects', yaxis2_title='Spends ($)', title='Channel spends and Prospects week-wise')
966
+ channel_sales_spends_fig.update_xaxes(showgrid=False)
967
+ channel_sales_spends_fig.update_yaxes(showgrid=False)
968
+ else:
969
+ raw_df = st.session_state['raw_df']
970
+ df = raw_df.sort_values(by='Date')
971
+ x = df.Date
972
+ scenario = class_from_dict(st.session_state['default_scenario_dict'])
973
+ _sales = scenario.constant + scenario.correction
974
+ channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
975
+ channel_sales_spends_fig.add_trace(go.Bar(
976
+ x=x,
977
+ y=_sales,
978
+ marker_color=color_palette[0], # You can choose a color from the palette
979
+ name='Prospects',
980
+ hovertemplate="Date:%{x}<br>Prospects:%{y:$.2s}",
981
+ ), secondary_y=False)
982
+
983
+ channel_sales_spends_fig.update_layout(xaxis_title='Date', yaxis_title='Prospects', yaxis2_title='Spends ($)', title='Channel spends and Prospects week-wise')
984
+ channel_sales_spends_fig.update_xaxes(showgrid=False)
985
+ channel_sales_spends_fig.update_yaxes(showgrid=False)
986
+
987
+ return channel_sales_spends_fig
988
+
989
+ def format_numbers(value, n_decimals=1,include_indicator = True):
990
+ if include_indicator:
991
+ return f'{CURRENCY_INDICATOR} {numerize(value,n_decimals)}'
992
+ else:
993
+ return f'{numerize(value,n_decimals)}'
994
+
995
+
996
+ def decimal_formater(num_string,n_decimals=1):
997
+ parts = num_string.split('.')
998
+ if len(parts) == 1:
999
+ return num_string+'.' + '0'*n_decimals
1000
+ else:
1001
+ to_be_padded = n_decimals - len(parts[-1])
1002
+ if to_be_padded > 0 :
1003
+ return num_string+'0'*to_be_padded
1004
+ else:
1005
+ return num_string
1006
+
1007
+
1008
+ def channel_name_formating(channel_name):
1009
+ name_mod = channel_name.replace('_', ' ')
1010
+ if name_mod.lower().endswith(' imp'):
1011
+ name_mod = name_mod.replace('Imp','Spend')
1012
+ elif name_mod.lower().endswith(' clicks'):
1013
+ name_mod = name_mod.replace('Clicks','Spend')
1014
+ return name_mod
1015
+
1016
+
1017
+ def send_email(email,message):
1018
+ s = smtplib.SMTP('smtp.gmail.com', 587)
1019
+ s.starttls()
1020
+ s.login("[email protected]", "jgydhpfusuremcol")
1021
+ s.sendmail("[email protected]", email, message)
1022
+ s.quit()
1023
+
1024
+ if __name__ == "__main__":
1025
+ initialize_data()