customeranalytics 0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. customeranalytics/__init__.py +319 -0
  2. customeranalytics/configs.py +480 -0
  3. customeranalytics/data_storage_configurations/__init__.py +245 -0
  4. customeranalytics/data_storage_configurations/data_access.py +165 -0
  5. customeranalytics/data_storage_configurations/data_works_pipeline.py +207 -0
  6. customeranalytics/data_storage_configurations/es_create_index.py +544 -0
  7. customeranalytics/data_storage_configurations/logger.py +36 -0
  8. customeranalytics/data_storage_configurations/query_es.py +157 -0
  9. customeranalytics/data_storage_configurations/reports.py +684 -0
  10. customeranalytics/data_storage_configurations/schedule_data_integration.py +355 -0
  11. customeranalytics/docs/queries.yaml +245 -0
  12. customeranalytics/docs/web_configs.yaml +2 -0
  13. customeranalytics/exploratory_analysis/__init__.py +109 -0
  14. customeranalytics/exploratory_analysis/churn.py +232 -0
  15. customeranalytics/exploratory_analysis/cohorts.py +535 -0
  16. customeranalytics/exploratory_analysis/descriptive_statistics.py +470 -0
  17. customeranalytics/exploratory_analysis/funnels.py +407 -0
  18. customeranalytics/exploratory_analysis/product_analytics.py +340 -0
  19. customeranalytics/exploratory_analysis/promotion_analytics.py +299 -0
  20. customeranalytics/exploratory_analysis/rfm.py +202 -0
  21. customeranalytics/exploratory_analysis/sample_data/sample_data_avg_order_count_per_promo_per_cust.csv +99 -0
  22. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_1_search.csv +2 -0
  23. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_2_search.csv +46 -0
  24. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_3_search.csv +2 -0
  25. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_4_search.csv +2 -0
  26. customeranalytics/exploratory_analysis/sample_data/sample_data_churn.csv +2 -0
  27. customeranalytics/exploratory_analysis/sample_data/sample_data_churn_weekly.csv +10 -0
  28. customeranalytics/exploratory_analysis/sample_data/sample_data_client_feature_predicted.csv +1590 -0
  29. customeranalytics/exploratory_analysis/sample_data/sample_data_client_kpis.csv +7060 -0
  30. customeranalytics/exploratory_analysis/sample_data/sample_data_clvrfm_anomaly.csv +561 -0
  31. customeranalytics/exploratory_analysis/sample_data/sample_data_clvsegments_amount.csv +8 -0
  32. customeranalytics/exploratory_analysis/sample_data/sample_data_customer_journey.csv +18 -0
  33. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_clv.csv +103 -0
  34. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_downloads.csv +68 -0
  35. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_1_to_2.csv +66 -0
  36. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_2_to_3.csv +64 -0
  37. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_3_to_4.csv +55 -0
  38. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_dimension_values.csv +199 -0
  39. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_funnel.csv +36 -0
  40. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_funnel_downloads.csv +68 -0
  41. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_inorganic_ratio.csv +6070 -0
  42. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_orders.csv +57 -0
  43. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_organic_orders.csv +64 -0
  44. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_products_of_sales.csv +12574 -0
  45. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_promotion_discount.csv +64 -0
  46. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_promotion_revenue.csv +6070 -0
  47. customeranalytics/exploratory_analysis/sample_data/sample_data_dcohort_anomaly.csv +6 -0
  48. customeranalytics/exploratory_analysis/sample_data/sample_data_dcohort_anomaly_2.csv +118 -0
  49. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver.csv +47 -0
  50. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver_kpis.csv +2 -0
  51. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver_weekday_hour.csv +25 -0
  52. customeranalytics/exploratory_analysis/sample_data/sample_data_dfunnel_anomaly.csv +118 -0
  53. customeranalytics/exploratory_analysis/sample_data/sample_data_dimension_kpis.csv +199 -0
  54. customeranalytics/exploratory_analysis/sample_data/sample_data_dorders_anomaly.csv +85 -0
  55. customeranalytics/exploratory_analysis/sample_data/sample_data_frequency_clusters.csv +6 -0
  56. customeranalytics/exploratory_analysis/sample_data/sample_data_frequency_recency.csv +3740 -0
  57. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_funnel.csv +25 -0
  58. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_funnel_downloads.csv +25 -0
  59. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_inorganic_ratio.csv +2353 -0
  60. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_orders.csv +25 -0
  61. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_organic_orders.csv +2353 -0
  62. customeranalytics/exploratory_analysis/sample_data/sample_data_inorganic_orders_per_promotion_per_day.csv +6070 -0
  63. customeranalytics/exploratory_analysis/sample_data/sample_data_kpis.csv +2 -0
  64. customeranalytics/exploratory_analysis/sample_data/sample_data_monetary_clusters.csv +6 -0
  65. customeranalytics/exploratory_analysis/sample_data/sample_data_monetary_frequency.csv +3740 -0
  66. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_funnel.csv +5 -0
  67. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_funnel_downloads.csv +5 -0
  68. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_orders.csv +4 -0
  69. customeranalytics/exploratory_analysis/sample_data/sample_data_most_combined_products.csv +11 -0
  70. customeranalytics/exploratory_analysis/sample_data/sample_data_most_ordered_categories.csv +11 -0
  71. customeranalytics/exploratory_analysis/sample_data/sample_data_most_ordered_products.csv +11 -0
  72. customeranalytics/exploratory_analysis/sample_data/sample_data_order_and_payment_amount_differences.csv +91 -0
  73. customeranalytics/exploratory_analysis/sample_data/sample_data_prepare.csv +101 -0
  74. customeranalytics/exploratory_analysis/sample_data/sample_data_prepare_weekday_hour.csv +25 -0
  75. customeranalytics/exploratory_analysis/sample_data/sample_data_product_kpis.csv +201 -0
  76. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_amount_accept.csv +11 -0
  77. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_amount_reject.csv +7 -0
  78. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_orders_accept.csv +11 -0
  79. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_orders_reject.csv +11 -0
  80. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_comparison.csv +91 -0
  81. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_kpis.csv +99 -0
  82. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_number_of_customer.csv +99 -0
  83. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_amount_accept.csv +81 -0
  84. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_amount_reject.csv +11 -0
  85. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_orders_accept.csv +55 -0
  86. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_orders_reject.csv +37 -0
  87. customeranalytics/exploratory_analysis/sample_data/sample_data_purchase_amount_distribution.csv +22 -0
  88. customeranalytics/exploratory_analysis/sample_data/sample_data_recency_clusters.csv +6 -0
  89. customeranalytics/exploratory_analysis/sample_data/sample_data_recency_monetary.csv +3740 -0
  90. customeranalytics/exploratory_analysis/sample_data/sample_data_rfm.csv +2001 -0
  91. customeranalytics/exploratory_analysis/sample_data/sample_data_ride.csv +101 -0
  92. customeranalytics/exploratory_analysis/sample_data/sample_data_ride_weekday_hour.csv +25 -0
  93. customeranalytics/exploratory_analysis/sample_data/sample_data_segmentation.csv +11 -0
  94. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_daily_before_after_amount.csv +10 -0
  95. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_daily_before_after_orders.csv +9 -0
  96. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_monthly_before_after_amount.csv +10 -0
  97. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_monthly_before_after_orders.csv +11 -0
  98. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_weekly_before_after_amount.csv +10 -0
  99. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_weekly_before_after_orders.csv +10 -0
  100. customeranalytics/exploratory_analysis/sample_data/sample_data_user_counts_per_order_seq.csv +47 -0
  101. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_order_per_user.csv +13 -0
  102. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_payment_amount.csv +13 -0
  103. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_session_per_user.csv +13 -0
  104. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_downloads.csv +13 -0
  105. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_1_to_2.csv +13 -0
  106. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_2_to_3.csv +13 -0
  107. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_3_to_4.csv +12 -0
  108. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_funnel.csv +25 -0
  109. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_funnel_downloads.csv +25 -0
  110. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_orders.csv +10 -0
  111. customeranalytics/ml_process/__init__.py +64 -0
  112. customeranalytics/ml_process/ab_test.py +615 -0
  113. customeranalytics/ml_process/anomaly_detection.py +456 -0
  114. customeranalytics/ml_process/clv_prediction.py +301 -0
  115. customeranalytics/ml_process/customer_segmentation.py +354 -0
  116. customeranalytics/ml_process/delivery_analytics.py +754 -0
  117. customeranalytics/utils.py +186 -0
  118. customeranalytics/web/app/__init__.py +37 -0
  119. customeranalytics/web/app/base/__init__.py +9 -0
  120. customeranalytics/web/app/base/forms.py +16 -0
  121. customeranalytics/web/app/base/models.py +43 -0
  122. customeranalytics/web/app/base/routes.py +126 -0
  123. customeranalytics/web/app/base/static/assets/css/app.css +20 -0
  124. customeranalytics/web/app/base/static/assets/fonts/Inter-Black.woff +0 -0
  125. customeranalytics/web/app/base/static/assets/fonts/Inter-Black.woff2 +0 -0
  126. customeranalytics/web/app/base/static/assets/fonts/Inter-BlackItalic.woff +0 -0
  127. customeranalytics/web/app/base/static/assets/fonts/Inter-BlackItalic.woff2 +0 -0
  128. customeranalytics/web/app/base/static/assets/fonts/Inter-Bold.woff +0 -0
  129. customeranalytics/web/app/base/static/assets/fonts/Inter-Bold.woff2 +0 -0
  130. customeranalytics/web/app/base/static/assets/fonts/Inter-BoldItalic.woff +0 -0
  131. customeranalytics/web/app/base/static/assets/fonts/Inter-BoldItalic.woff2 +0 -0
  132. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBold.woff +0 -0
  133. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBold.woff2 +0 -0
  134. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBoldItalic.woff +0 -0
  135. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBoldItalic.woff2 +0 -0
  136. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLight-BETA.woff +0 -0
  137. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLight-BETA.woff2 +0 -0
  138. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLightItalic-BETA.woff +0 -0
  139. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLightItalic-BETA.woff2 +0 -0
  140. customeranalytics/web/app/base/static/assets/fonts/Inter-Italic.woff +0 -0
  141. customeranalytics/web/app/base/static/assets/fonts/Inter-Italic.woff2 +0 -0
  142. customeranalytics/web/app/base/static/assets/fonts/Inter-Light-BETA.woff +0 -0
  143. customeranalytics/web/app/base/static/assets/fonts/Inter-Light-BETA.woff2 +0 -0
  144. customeranalytics/web/app/base/static/assets/fonts/Inter-LightItalic-BETA.woff +0 -0
  145. customeranalytics/web/app/base/static/assets/fonts/Inter-LightItalic-BETA.woff2 +0 -0
  146. customeranalytics/web/app/base/static/assets/fonts/Inter-Medium.woff +0 -0
  147. customeranalytics/web/app/base/static/assets/fonts/Inter-Medium.woff2 +0 -0
  148. customeranalytics/web/app/base/static/assets/fonts/Inter-MediumItalic.woff +0 -0
  149. customeranalytics/web/app/base/static/assets/fonts/Inter-MediumItalic.woff2 +0 -0
  150. customeranalytics/web/app/base/static/assets/fonts/Inter-Regular.woff +0 -0
  151. customeranalytics/web/app/base/static/assets/fonts/Inter-Regular.woff2 +0 -0
  152. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBold.woff +0 -0
  153. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBold.woff2 +0 -0
  154. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBoldItalic.woff +0 -0
  155. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBoldItalic.woff2 +0 -0
  156. customeranalytics/web/app/base/static/assets/fonts/Inter-Thin-BETA.woff +0 -0
  157. customeranalytics/web/app/base/static/assets/fonts/Inter-Thin-BETA.woff2 +0 -0
  158. customeranalytics/web/app/base/static/assets/fonts/Inter-ThinItalic-BETA.woff +0 -0
  159. customeranalytics/web/app/base/static/assets/fonts/Inter-ThinItalic-BETA.woff2 +0 -0
  160. customeranalytics/web/app/base/static/assets/fonts/Inter-italic.var.woff2 +0 -0
  161. customeranalytics/web/app/base/static/assets/fonts/Inter-upright.var.woff2 +0 -0
  162. customeranalytics/web/app/base/static/assets/fonts/Inter.var.woff2 +0 -0
  163. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.eot +0 -0
  164. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.svg +3570 -0
  165. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.ttf +0 -0
  166. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.woff +0 -0
  167. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.woff2 +0 -0
  168. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.eot +0 -0
  169. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.svg +801 -0
  170. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.ttf +0 -0
  171. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.woff +0 -0
  172. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.woff2 +0 -0
  173. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.eot +0 -0
  174. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.svg +5028 -0
  175. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.ttf +0 -0
  176. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.woff +0 -0
  177. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.woff2 +0 -0
  178. customeranalytics/web/app/base/static/assets/img/avatars/avatar-1.png +0 -0
  179. customeranalytics/web/app/base/static/assets/img/avatars/avatar-2.png +0 -0
  180. customeranalytics/web/app/base/static/assets/img/avatars/avatar-3.png +0 -0
  181. customeranalytics/web/app/base/static/assets/img/avatars/avatar-4.png +0 -0
  182. customeranalytics/web/app/base/static/assets/img/avatars/avatar-5.png +0 -0
  183. customeranalytics/web/app/base/static/assets/img/avatars/info.jpeg +0 -0
  184. customeranalytics/web/app/base/static/assets/img/icons/customanality.png +0 -0
  185. customeranalytics/web/app/base/static/assets/img/icons/icon-48x48.png +0 -0
  186. customeranalytics/web/app/base/static/assets/js/app.js +2 -0
  187. customeranalytics/web/app/base/static/assets/js/app.js.LICENSE +566 -0
  188. customeranalytics/web/app/base/static/assets/js/app.js.LICENSE.txt +556 -0
  189. customeranalytics/web/app/base/static/assets/js/modules/bootstrap.js +15 -0
  190. customeranalytics/web/app/base/static/assets/js/modules/chartjs.js +4 -0
  191. customeranalytics/web/app/base/static/assets/js/modules/feather.js +8 -0
  192. customeranalytics/web/app/base/static/assets/js/modules/flatpickr.js +4 -0
  193. customeranalytics/web/app/base/static/assets/js/modules/moment.js +4 -0
  194. customeranalytics/web/app/base/static/assets/js/modules/sidebar.js +23 -0
  195. customeranalytics/web/app/base/static/assets/js/modules/theme.js +16 -0
  196. customeranalytics/web/app/base/templates/accounts/login.html +81 -0
  197. customeranalytics/web/app/base/templates/accounts/register.html +80 -0
  198. customeranalytics/web/app/base/templates/includes/footer.html +28 -0
  199. customeranalytics/web/app/base/templates/includes/navigation.html +51 -0
  200. customeranalytics/web/app/base/templates/includes/scripts.html +3 -0
  201. customeranalytics/web/app/base/templates/includes/sidebar.html +146 -0
  202. customeranalytics/web/app/base/templates/layouts/base-fullscreen.html +36 -0
  203. customeranalytics/web/app/base/templates/layouts/base.html +84 -0
  204. customeranalytics/web/app/base/util.py +30 -0
  205. customeranalytics/web/app/home/__init__.py +9 -0
  206. customeranalytics/web/app/home/forms.py +1039 -0
  207. customeranalytics/web/app/home/models.py +438 -0
  208. customeranalytics/web/app/home/profiles.py +310 -0
  209. customeranalytics/web/app/home/routes.py +386 -0
  210. customeranalytics/web/app/home/search.py +288 -0
  211. customeranalytics/web/app/home/static/assets/img/avatars/avatar-1.png +0 -0
  212. customeranalytics/web/app/home/static/assets/img/avatars/avatar-2.png +0 -0
  213. customeranalytics/web/app/home/static/assets/img/avatars/avatar-3.png +0 -0
  214. customeranalytics/web/app/home/static/assets/img/avatars/avatar-4.png +0 -0
  215. customeranalytics/web/app/home/static/assets/img/avatars/avatar-5.png +0 -0
  216. customeranalytics/web/app/home/static/assets/img/icons/customanality.png +0 -0
  217. customeranalytics/web/app/home/static/assets/img/icons/icon-48x48.png +0 -0
  218. customeranalytics/web/app/home/templates/abtest-product.html +280 -0
  219. customeranalytics/web/app/home/templates/abtest-promotion.html +362 -0
  220. customeranalytics/web/app/home/templates/abtest-segments.html +298 -0
  221. customeranalytics/web/app/home/templates/add-data-delivery.html +184 -0
  222. customeranalytics/web/app/home/templates/add-data-product.html +177 -0
  223. customeranalytics/web/app/home/templates/add-data-purchase.html +392 -0
  224. customeranalytics/web/app/home/templates/anomaly.html +261 -0
  225. customeranalytics/web/app/home/templates/clv.html +211 -0
  226. customeranalytics/web/app/home/templates/cohorts.html +308 -0
  227. customeranalytics/web/app/home/templates/customer-segmentation.html +308 -0
  228. customeranalytics/web/app/home/templates/data-es.html +152 -0
  229. customeranalytics/web/app/home/templates/data-execute.html +397 -0
  230. customeranalytics/web/app/home/templates/delivery.html +404 -0
  231. customeranalytics/web/app/home/templates/funnel-customer.html +240 -0
  232. customeranalytics/web/app/home/templates/funnel-session.html +236 -0
  233. customeranalytics/web/app/home/templates/index.html +524 -0
  234. customeranalytics/web/app/home/templates/index2.html +515 -0
  235. customeranalytics/web/app/home/templates/page-403.html +46 -0
  236. customeranalytics/web/app/home/templates/page-404.html +45 -0
  237. customeranalytics/web/app/home/templates/page-500.html +45 -0
  238. customeranalytics/web/app/home/templates/pages-blank.html +33 -0
  239. customeranalytics/web/app/home/templates/pages-sign-in.html +67 -0
  240. customeranalytics/web/app/home/templates/pages-sign-up.html +61 -0
  241. customeranalytics/web/app/home/templates/product.html +203 -0
  242. customeranalytics/web/app/home/templates/profile.html +1009 -0
  243. customeranalytics/web/app/home/templates/rfm.html +254 -0
  244. customeranalytics/web/app/home/templates/search.html +167 -0
  245. customeranalytics/web/app/home/templates/settings.html +205 -0
  246. customeranalytics/web/app/home/templates/stats-desc.html +230 -0
  247. customeranalytics/web/app/home/templates/stats-purchase.html +221 -0
  248. customeranalytics/web/config.py +30 -0
  249. customeranalytics/web/db.sqlite3 +0 -0
  250. customeranalytics/web/run.py +30 -0
  251. customeranalytics-0.1.dist-info/METADATA +1102 -0
  252. customeranalytics-0.1.dist-info/RECORD +254 -0
  253. customeranalytics-0.1.dist-info/WHEEL +4 -0
  254. customeranalytics-0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,470 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+ import sys, os, inspect
4
+ import warnings
5
+ warnings.filterwarnings("ignore")
6
+
7
+ currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
8
+ parentdir = os.path.dirname(currentdir)
9
+ sys.path.insert(0, parentdir)
10
+
11
+ from customeranalytics.configs import default_es_port, default_es_host, default_query_date, time_periods
12
+ from customeranalytics.utils import *
13
+ from customeranalytics.data_storage_configurations.query_es import QueryES
14
+
15
+
16
+ class Stats:
17
+ """
18
+ There are some overall values that need to check each day for businesses.
19
+ These values are also crucial metrics for the dashboards.
20
+
21
+ Here are the basic aggregated values;
22
+ - total_orders
23
+ - last_week_orders
24
+ - total_revenue
25
+ - last_week_revenue
26
+ - total_visitors
27
+ - last_week_visitors
28
+ - total_discount
29
+ - last_week_discount
30
+ - average_basket_value_per_user
31
+ - overall_payment_distribution
32
+ - weekly_average_order_per_user
33
+ - weekly_average_session_per_user
34
+ - weekly_average_payment_amount
35
+ - daily_orders
36
+ - weekly_orders
37
+ - monthly_orders
38
+ - purchase_amount_distribution
39
+
40
+
41
+
42
+ !!!!
43
+ ******* ******** *****
44
+ Dimensional Stats:
45
+ Descriptive Statistics must be created individually for dimensions.
46
+ For instance, the Data set contains locations dimension.
47
+ In this case, each location of 'orders' and 'downloads' indexes must be created individually.
48
+ by using 'download_index' and 'order_index' dimension can be assigned in order to create the descriptive Stats
49
+
50
+ download_index; downloads_location1 this will be the location dimension of
51
+ parameters in order to query downloads indexes; 'location1'.
52
+ download_index; orders_location1 this will be the location dimension of
53
+ parameters in order to query orders indexes; 'location1'.
54
+ ******* ******** *****
55
+ !!!
56
+ """
57
+
58
+ def __init__(self,
59
+ host=None,
60
+ port=None,
61
+ download_index='downloads',
62
+ order_index='orders'):
63
+ """
64
+ ******* ******** *****
65
+ Dimensional Stats:
66
+ Descriptive Statistics must be created individually for dimensions.
67
+ For instance, the Data set contains locations dimension.
68
+ In this case, each location of 'orders' and 'downloads' indexes must be created individually.
69
+ by using 'download_index' and 'order_index' dimension can be assigned in order to create the descriptive Stats
70
+
71
+ download_index; downloads_location1 this will be the location dimension of
72
+ parameters in order to query downloads indexes; 'location1'.
73
+ download_index; orders_location1 this will be the location dimension of
74
+ parameters in order to query orders indexes; 'location1'.
75
+ ******* ******** *****
76
+ !!!
77
+
78
+ :param host: elasticsearch host
79
+ :param port: elasticsearch port
80
+ :param download_index: elasticsearch port
81
+ :param order_index: elasticsearch port
82
+ """
83
+ self.port = default_es_port if port is None else port
84
+ self.host = default_es_host if host is None else host
85
+ self.download_index = download_index
86
+ self.order_index = order_index
87
+ self.query_es = QueryES(port=port, host=host)
88
+ self.orders_field_data = ["id", "session_start_date", "client",
89
+ "payment_amount", "discount_amount", "actions.purchased", "dimension"]
90
+ self.stats = ["total_orders", "last_week_orders",
91
+ "total_revenue", "last_week_revenue",
92
+ "total_visitors", "last_week_visitors",
93
+ "total_discount", "last_week_discount",
94
+ "average_basket_value_per_user",
95
+ "hourly_orders", "daily_orders", "weekly_orders", "monthly_orders",
96
+ "purchase_amount_distribution", "weekly_average_order_per_user",
97
+ "weekly_average_session_per_user", "weekly_average_payment_amount", "user_counts_per_order_seq",
98
+ "hourly_revenue", "daily_revenue", "weekly_revenue", "monthly_revenue",
99
+ "total_order_count_per_customer", "dimension_kpis", "daily_dimension_values"]
100
+ self.last_week = None
101
+ self.time_periods = time_periods # ["daily", "weekly", 'monthly']
102
+ self.orders = pd.DataFrame()
103
+ self.dimension_kpis = pd.DataFrame()
104
+ self.daily_dimension_values = pd.DataFrame()
105
+ self.results = {}
106
+
107
+ def dimensional_query(self, boolean_query=None):
108
+ if dimension_decision(self.order_index):
109
+ if boolean_query is None:
110
+ boolean_query = [{"term": {"dimension": self.order_index}}]
111
+ else:
112
+ boolean_query += [{"term": {"dimension": self.order_index}}]
113
+ return boolean_query
114
+
115
+ def get_data(self, start_date=None):
116
+ """
117
+ query orders index to collect the data with columns that are
118
+ "id", "session_start_date", "client", "payment_amount", "discount_amount", "actions.purchased".
119
+ :param start_date: starting date of query
120
+ :return: data-frame individual order transactions.
121
+ """
122
+ start_date = default_query_date if start_date is None else start_date
123
+ if len(self.orders) == 0:
124
+ self.query_es = QueryES(port=self.port, host=self.host)
125
+ self.query_es.query_builder(fields=self.orders_field_data,
126
+ date_queries=[{"range": {"session_start_date": {"gte": start_date}}}],
127
+ boolean_queries=self.dimensional_query())
128
+ self.orders = pd.DataFrame(self.query_es.get_data_from_es())
129
+ self.orders['date'] = self.orders['session_start_date'].apply(lambda x: convert_to_date(x))
130
+
131
+ def get_last_week(self):
132
+ """
133
+ in order to compare the recent week and last week the previous date of the whole order data is found.
134
+ :return: datetime
135
+ """
136
+ self.last_week = max(self.orders['date']) - datetime.timedelta(days=7)
137
+
138
+ def get_time_period(self):
139
+ """
140
+ converting date column of values into the time_periods (hourly weekly, monthly,..)
141
+ orders; total data (orders/downloads data with actions)
142
+ final data; data set with time periods
143
+ """
144
+ for p in list(zip(self.time_periods,
145
+ [convert_str_to_hour, convert_dt_to_day_str, find_week_of_monday, convert_dt_to_month_str])):
146
+ self.orders[p[0]] = self.orders["date"].apply(lambda x: p[1](x))
147
+
148
+ def total_orders(self):
149
+ """
150
+ Total number of orders stored in orders index
151
+ :return: integer
152
+ """
153
+ return len(self.orders[self.orders['actions.purchased'] == True]['id'])
154
+
155
+ def last_week_orders(self):
156
+ """
157
+ Total number of orders in last 7 days
158
+ :return: integer
159
+ """
160
+ return len(self.orders[(self.orders['actions.purchased'] == True) &
161
+ (self.orders['date'] > self.last_week)]['id'])
162
+
163
+ def total_revenue(self):
164
+ """
165
+ Total payment amount of orders
166
+ :return: float
167
+ """
168
+ return sum(self.orders[self.orders['actions.purchased'] == True]['payment_amount'])
169
+
170
+ def last_week_revenue(self):
171
+ """
172
+ Total payment amount of orders in last 7 days
173
+ :return: float
174
+ """
175
+ return sum(self.orders[(self.orders['actions.purchased'] == True) &
176
+ (self.orders['date'] > self.last_week)]['payment_amount'])
177
+
178
+ def total_visitors(self):
179
+ """
180
+ Total number of unique visitors
181
+ :return: integer
182
+ """
183
+ return len(self.orders['client'].unique())
184
+
185
+ def last_week_visitors(self):
186
+ """
187
+ Total number of unique visitors in last 7 days
188
+ :return: integer
189
+ """
190
+ return len(self.orders['client'].unique())
191
+
192
+ def total_discount(self):
193
+ """
194
+ Total discount amount of orders
195
+ :return: float
196
+ """
197
+ return sum(self.orders[self.orders['actions.purchased'] == True]['discount_amount'])
198
+
199
+ def last_week_discount(self):
200
+ """
201
+ Total discount amount of orders in last 7 days
202
+ :return: integer
203
+ """
204
+ return sum(self.orders[(self.orders['actions.purchased'] == True) &
205
+ (self.orders['date'] > self.last_week)]['discount_amount'])
206
+
207
+ def average_basket_value_per_user(self):
208
+ """
209
+ Average payment amount of orders per user who has orders
210
+ :return: float
211
+ """
212
+ return np.mean(self.orders[(self.orders['actions.purchased'] == True)].groupby("client").agg(
213
+ {"payment_amount": "mean"}).reset_index()['payment_amount'])
214
+
215
+ def hourly_orders(self):
216
+ """
217
+ Average of total order count per day
218
+ :return: data-frame
219
+ """
220
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby('hourly').agg(
221
+ {'id': 'count'}).reset_index().rename(columns={'id': 'orders'}).groupby('hourly').agg(
222
+ {'orders': 'mean'}).reset_index()
223
+
224
+ def daily_orders(self):
225
+ """
226
+ total number of orders per day
227
+ :return: data-frame
228
+ """
229
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby("daily").agg(
230
+ {"id": "count"}).reset_index().rename(columns={"id": "orders"})
231
+
232
+ def weekly_orders(self):
233
+ """
234
+ total number of orders per week
235
+ :return: data-frame
236
+ """
237
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby("weekly").agg(
238
+ {"id": "count"}).reset_index().rename(columns={"id": "orders"})
239
+
240
+ def monthly_orders(self):
241
+ """
242
+ total number of orders per month
243
+ :return:
244
+ """
245
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby("monthly").agg(
246
+ {"id": "count"}).reset_index().rename(columns={"id": "orders"})
247
+
248
+ def hourly_revenue(self):
249
+ """
250
+ total revenue per hour
251
+ :return: data-frame
252
+ """
253
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby('hourly').agg(
254
+ {"payment_amount": "sum"}).reset_index()
255
+
256
+ def daily_revenue(self):
257
+ """
258
+ total revenue per day
259
+ :return: data-frame
260
+ """
261
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby("daily").agg(
262
+ {"payment_amount": "sum"}).reset_index()
263
+
264
+ def weekly_revenue(self):
265
+ """
266
+ total revenue per week
267
+ :return: data-frame
268
+ """
269
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby("weekly").agg(
270
+ {"payment_amount": "sum"}).reset_index()
271
+
272
+ def monthly_revenue(self):
273
+ """
274
+ total revenue per month
275
+ :return:
276
+ """
277
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby("monthly").agg(
278
+ {"payment_amount": "sum"}).reset_index()
279
+
280
+ def purchase_amount_distribution(self):
281
+ """
282
+ Payment values (purchased orders) of Distribution
283
+ :return: data-frame; payment_bins, orders
284
+ """
285
+ _orders = self.orders[(self.orders['actions.purchased'] == True)]
286
+ _amount = list(_orders['payment_amount'])
287
+ _min_amount, _max_amount = min(_amount), max(_amount)
288
+ _range = (_max_amount - _min_amount) / 20
289
+
290
+ bins = {}
291
+ for i in range(0, 20):
292
+ bins[i] = {"min": _min_amount + (_range * i), "max": _min_amount + (_range * (i + 1))}
293
+
294
+ _orders['payment_bins'] = _orders['payment_amount'].apply(
295
+ lambda x: str(round(_min_amount + (int((x - _min_amount) / _range) * _range), 2)) if x == x else '-')
296
+ _orders = _orders.groupby("payment_bins").agg({"id": "count"}).reset_index().rename(columns={"id": "orders"})
297
+ _orders['payment_bins'] = _orders['payment_bins'].apply(lambda x: str(x))
298
+ return _orders
299
+
300
+ def weekly_average_order_per_user(self):
301
+ """
302
+ Weekly average order per user
303
+ """
304
+ _orders = self.orders[(self.orders['actions.purchased'] == True)].groupby(["weekly", "client"]).agg(
305
+ {"id": "count"}).reset_index().rename(columns={"id": "orders"})
306
+ return _orders.groupby("weekly").agg({"orders": "mean"}).reset_index()
307
+
308
+ def weekly_average_session_per_user(self):
309
+ """
310
+ Weekly average session per user
311
+ """
312
+ _orders = self.orders.groupby(["weekly", "client"]).agg(
313
+ {"id": "count"}).reset_index().rename(columns={"id": "sessions"})
314
+
315
+ return _orders.groupby("weekly").agg({"sessions": "mean"}).reset_index()
316
+
317
+ def weekly_average_payment_amount(self):
318
+ """
319
+ Weekly average payment amount
320
+ """
321
+ return self.orders[(self.orders['actions.purchased'] == True)].groupby("weekly").agg(
322
+ {"payment_amount": "mean"}).reset_index()
323
+
324
+ def user_order_count_per_order_seq(self):
325
+ """
326
+ Customers' number of orders are calculated. The number of unique customer per total order count are calculated.
327
+ """
328
+ self.orders['order_seq_num'] = self.orders.sort_values(by=['client', 'date'],
329
+ ascending=True).groupby(['client'])['client'].cumcount() + 1
330
+ self.orders_freq = self.orders.query("order_seq_num != 1")
331
+ self.orders_freq = self.orders_freq.groupby("order_seq_num").agg({"id": "count"}).reset_index()
332
+ self.orders_freq = self.orders_freq.sort_values(by='order_seq_num', ascending=True)
333
+ self.orders_freq = self.orders_freq.rename(columns={"id": "frequency"})
334
+ self.orders_freq['order_seq_num'] = self.orders_freq['order_seq_num'].apply(lambda x: str(x))
335
+ return self.orders_freq
336
+
337
+ def get_customer_total_order_count(self):
338
+ """
339
+ total order count per customer
340
+ """
341
+ return self.orders.groupby("client").agg(
342
+ {"id": lambda x: len(np.unique(x))}).reset_index().rename(columns={"id": "order_count"})
343
+
344
+ def get_dimension_kpis(self):
345
+ if not dimension_decision(self.order_index):
346
+ _dimensions = list(self.orders['dimension'].unique())
347
+ print(_dimensions)
348
+ if len(_dimensions) > 1:
349
+ self.dimension_kpis = self.orders.groupby(["dimension"]).agg(
350
+ {"id": lambda x: len(np.unique(x)), "payment_amount": "sum",
351
+ "discount_amount": "sum", "client": lambda x: len(np.unique(x))
352
+ }).reset_index().rename(columns={"id": "order_count", "client": "client_client_count"})
353
+ return self.dimension_kpis
354
+
355
+ def get_daily_dimension_values(self):
356
+ if not dimension_decision(self.order_index):
357
+ _dimensions = list(self.orders['dimension'].unique())
358
+ if len(_dimensions) > 1:
359
+ self.daily_dimension_values = self.orders.groupby(["dimension", "daily"]).agg(
360
+ {"id": lambda x: len(np.unique(x)), "payment_amount": "sum",
361
+ "discount_amount": "sum", "client": lambda x: len(np.unique(x))
362
+ }).reset_index().rename(columns={"id": "order_count", "client": "client_count"})
363
+ return self.daily_dimension_values
364
+
365
+ def execute_descriptive_stats(self, start_date=None):
366
+ """
367
+ 1. Get order data from the order index.
368
+ 2. Create time periods, weekly, daily, monthly
369
+ 3. Find last week start date
370
+ 4. Iterate metrics in order to calculate individually
371
+ 5. Insert separate metrics which are data-frame stored individually.
372
+ The rest of them are merged and stored as a one-row data-frame.
373
+ """
374
+ self.get_data(start_date=start_date)
375
+ self.get_time_period()
376
+ self.get_last_week()
377
+ for metric in list(zip(self.stats, [self.total_orders, self.last_week_orders,
378
+ self.total_revenue, self.last_week_revenue,
379
+ self.total_visitors, self.last_week_visitors,
380
+ self.total_discount, self.last_week_discount,
381
+ self.average_basket_value_per_user,
382
+ self.hourly_orders,
383
+ self.daily_orders,
384
+ self.weekly_orders,
385
+ self.monthly_orders,
386
+ self.purchase_amount_distribution,
387
+ self.weekly_average_order_per_user, self.weekly_average_session_per_user,
388
+ self.weekly_average_payment_amount,
389
+ self.user_order_count_per_order_seq,
390
+ self.hourly_revenue, self.daily_revenue,
391
+ self.weekly_revenue, self.monthly_revenue,
392
+ self.get_customer_total_order_count,
393
+ self.get_dimension_kpis,
394
+ self.get_daily_dimension_values
395
+ ])):
396
+ print("stat name :", metric[0])
397
+ if metric[0] in ["hourly_revenue", "daily_revenue", "weekly_revenue", "monthly_revenue",
398
+ "hourly_orders", "weekly_orders", "monthly_orders", "daily_orders",
399
+ "purchase_amount_distribution", "weekly_average_order_per_user",
400
+ "weekly_average_session_per_user",
401
+ "weekly_average_payment_amount", "user_counts_per_order_seq",
402
+ "total_order_count_per_customer", "dimension_kpis", "daily_dimension_values"]:
403
+ self.insert_into_reports_index(metric[1]().to_dict('records'),
404
+ start_date,
405
+ filters={"type": metric[0]},
406
+ index=self.order_index)
407
+ else:
408
+ self.results[metric[0]] = metric[1]()
409
+ self.insert_into_reports_index([self.results],
410
+ start_date,
411
+ filters={"type": ''},
412
+ index=self.order_index)
413
+
414
+ def insert_into_reports_index(self, stats, start_date, filters={}, index='orders'):
415
+ """
416
+ via query_es.py, each report can be inserted into the reports index with the given format.
417
+ {"id": unique report id,
418
+ "report_date": start_date or current date,
419
+ "report_name": "stats",
420
+ "index": "main",
421
+ "report_types": {
422
+ "type": "overall", "weekly_orders", "daily_orders", "monthly_orders"
423
+ },
424
+ "data": stats (list of dictionaries)
425
+ }
426
+ :param stats: overall, weekly_orders, daily_orders, monthly_orders
427
+ :param start_date: datetime
428
+ :param filters: {"type": "overall" or "weekly_orders" or "daily_orders" or "monthly_orders"}
429
+ :param index: dimensionality of data index orders_location1 ; dimension = location1
430
+ """
431
+ list_of_obj = [{"id": np.random.randint(200000000),
432
+ "report_date": current_date_to_day().isoformat() if start_date is None else start_date,
433
+ "report_name": "stats",
434
+ "index": get_index_group(index),
435
+ "report_types": filters,
436
+ "data": stats}]
437
+
438
+ self.query_es.insert_data_to_index(list_of_obj, index='reports')
439
+
440
+ def fetch(self, stats, start_date=None):
441
+ """
442
+ query format;
443
+ queries = {"stats": "overall"}
444
+ queries = {"stats": "weekly_orders"}
445
+ weekly orders
446
+ 0 2020-12-07T00:00:00 3
447
+ 1 2020-12-14T00:00:00 36687
448
+ 2 2020-12-21T00:00:00 38166
449
+ :param stats: overall, weekly_orders, daily_orders, monthly_orders
450
+ :param start_date:
451
+ :return: data-frame
452
+ """
453
+
454
+ boolean_queries = [{"term": {"report_name": "stats"}},
455
+ {"term": {"report_types.type": stats}},
456
+ {"term": {"index": get_index_group(self.order_index)}}]
457
+ date_queries = []
458
+ if start_date is not None:
459
+ date_queries = [{"range": {"report_date": {"gte": convert_to_iso_format(start_date)}}}]
460
+
461
+ self.query_es = QueryES(port=self.port,
462
+ host=self.host)
463
+ self.query_es.query_builder(fields=None, _source=True,
464
+ boolean_queries=boolean_queries,
465
+ date_queries=date_queries)
466
+ _res = self.query_es.get_data_from_es(index="reports")
467
+ _data = pd.DataFrame()
468
+ if len(_res) != 0:
469
+ _data = pd.DataFrame(_res[0]['_source']['data'])
470
+ return _data