DavMelchi commited on
Commit
75a24b6
·
1 Parent(s): a622d3b

Add worst high-traffic low-availability sites analysis and daily availability trends per RAT with SLA comparison

Browse files
Files changed (1) hide show
  1. apps/kpi_analysis/trafic_analysis.py +152 -0
apps/kpi_analysis/trafic_analysis.py CHANGED
@@ -850,6 +850,158 @@ if st.button(" Run Analysis"):
850
  st.subheader("Multi-RAT Availability by site (post-period)")
851
  st.dataframe(multi_rat_df.round(2))
852
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
853
  TraficAnalysis.last_period_df = last_period
854
 
855
  #######################################################################################################"""
 
850
  st.subheader("Multi-RAT Availability by site (post-period)")
851
  st.dataframe(multi_rat_df.round(2))
852
 
853
+ worst_2g = None
854
+ if (
855
+ "2g_avail_post" in multi_rat_df.columns
856
+ and "ok_2g_post" in multi_rat_df.columns
857
+ and "post_total_data_trafic" in multi_rat_df.columns
858
+ ):
859
+ tmp = multi_rat_df[
860
+ (multi_rat_df["ok_2g_post"] == False)
861
+ & multi_rat_df["post_total_data_trafic"].notna()
862
+ ].copy()
863
+ if not tmp.empty:
864
+ worst_2g = tmp.sort_values(
865
+ "post_total_data_trafic", ascending=False
866
+ ).head(number_of_top_trafic_sites)
867
+
868
+ worst_3g = None
869
+ if (
870
+ "3g_avail_post" in multi_rat_df.columns
871
+ and "ok_3g_post" in multi_rat_df.columns
872
+ and "post_total_data_trafic" in multi_rat_df.columns
873
+ ):
874
+ tmp = multi_rat_df[
875
+ (multi_rat_df["ok_3g_post"] == False)
876
+ & multi_rat_df["post_total_data_trafic"].notna()
877
+ ].copy()
878
+ if not tmp.empty:
879
+ worst_3g = tmp.sort_values(
880
+ "post_total_data_trafic", ascending=False
881
+ ).head(number_of_top_trafic_sites)
882
+
883
+ worst_lte = None
884
+ if (
885
+ "lte_avail_post" in multi_rat_df.columns
886
+ and "ok_lte_post" in multi_rat_df.columns
887
+ and "post_total_data_trafic" in multi_rat_df.columns
888
+ ):
889
+ tmp = multi_rat_df[
890
+ (multi_rat_df["ok_lte_post"] == False)
891
+ & multi_rat_df["post_total_data_trafic"].notna()
892
+ ].copy()
893
+ if not tmp.empty:
894
+ worst_lte = tmp.sort_values(
895
+ "post_total_data_trafic", ascending=False
896
+ ).head(number_of_top_trafic_sites)
897
+
898
+ st.subheader(
899
+ f"Worst high-traffic & low-availability sites by RAT (top {number_of_top_trafic_sites}, post-period)"
900
+ )
901
+ tab_2g, tab_3g, tab_lte = st.tabs(["2G", "3G", "LTE"])
902
+
903
+ with tab_2g:
904
+ if worst_2g is not None and not worst_2g.empty:
905
+ st.dataframe(worst_2g.round(2))
906
+ else:
907
+ st.info(
908
+ "No 2G sites with low availability and significant traffic in post-period."
909
+ )
910
+
911
+ with tab_3g:
912
+ if worst_3g is not None and not worst_3g.empty:
913
+ st.dataframe(worst_3g.round(2))
914
+ else:
915
+ st.info(
916
+ "No 3G sites with low availability and significant traffic in post-period."
917
+ )
918
+
919
+ with tab_lte:
920
+ if worst_lte is not None and not worst_lte.empty:
921
+ st.dataframe(worst_lte.round(2))
922
+ else:
923
+ st.info(
924
+ "No LTE sites with low availability and significant traffic in post-period."
925
+ )
926
+
927
+ # Temporal availability analysis - daily averages per RAT
928
+ if any(
929
+ col in full_df.columns
930
+ for col in ["2g_tch_avail", "3g_cell_avail", "lte_cell_avail"]
931
+ ):
932
+ temp_df = full_df.copy()
933
+ temp_df["date_only"] = temp_df["date"].dt.date
934
+
935
+ agg_dict = {}
936
+ if "2g_tch_avail" in temp_df.columns:
937
+ agg_dict["2g_tch_avail"] = "mean"
938
+ if "3g_cell_avail" in temp_df.columns:
939
+ agg_dict["3g_cell_avail"] = "mean"
940
+ if "lte_cell_avail" in temp_df.columns:
941
+ agg_dict["lte_cell_avail"] = "mean"
942
+
943
+ daily_avail = (
944
+ temp_df.groupby("date_only", as_index=False).agg(agg_dict)
945
+ if agg_dict
946
+ else pd.DataFrame()
947
+ )
948
+
949
+ if not daily_avail.empty:
950
+ rename_map = {}
951
+ if "2g_tch_avail" in daily_avail.columns:
952
+ rename_map["2g_tch_avail"] = "2G"
953
+ if "3g_cell_avail" in daily_avail.columns:
954
+ rename_map["3g_cell_avail"] = "3G"
955
+ if "lte_cell_avail" in daily_avail.columns:
956
+ rename_map["lte_cell_avail"] = "LTE"
957
+
958
+ daily_avail = daily_avail.rename(columns=rename_map)
959
+
960
+ value_cols = [c for c in daily_avail.columns if c != "date_only"]
961
+ if value_cols:
962
+ daily_melt = daily_avail.melt(
963
+ id_vars="date_only",
964
+ value_vars=value_cols,
965
+ var_name="RAT",
966
+ value_name="availability",
967
+ )
968
+
969
+ st.subheader("Daily average availability per RAT")
970
+ fig = px.line(
971
+ daily_melt,
972
+ x="date_only",
973
+ y="availability",
974
+ color="RAT",
975
+ markers=True,
976
+ )
977
+ st.plotly_chart(fig)
978
+
979
+ degraded_rows = []
980
+ for rat_name, sla_value in [
981
+ ("2G", sla_2g),
982
+ ("3G", sla_3g),
983
+ ("LTE", sla_lte),
984
+ ]:
985
+ if rat_name in daily_avail.columns:
986
+ series = daily_avail[rat_name]
987
+ mask = series < sla_value
988
+ for d, val in zip(
989
+ daily_avail.loc[mask, "date_only"], series[mask]
990
+ ):
991
+ degraded_rows.append(
992
+ {
993
+ "RAT": rat_name,
994
+ "date": d,
995
+ "avg_availability": val,
996
+ "SLA": sla_value,
997
+ }
998
+ )
999
+
1000
+ if degraded_rows:
1001
+ degraded_df = pd.DataFrame(degraded_rows)
1002
+ st.subheader("Days with average availability below SLA")
1003
+ st.dataframe(degraded_df.round(2))
1004
+
1005
  TraficAnalysis.last_period_df = last_period
1006
 
1007
  #######################################################################################################"""