DavMelchi commited on
Commit
031d4db
·
1 Parent(s): 5d12505

Wcel capacity V1 completed

Browse files
apps/kpi_analysis/wcel_capacity.py CHANGED
@@ -89,10 +89,12 @@ if uploaded_file is not None:
89
  )
90
 
91
  if results is not None:
 
 
92
 
93
- kpi_df = results[0]
94
-
95
- WcelCapacity.final_results = convert_dfs([kpi_df], ["kpi_df"])
96
  st.download_button(
97
  on_click="ignore",
98
  type="primary",
@@ -101,4 +103,217 @@ if uploaded_file is not None:
101
  file_name="WCEL_Capacity_Report.xlsx",
102
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
103
  )
104
- st.write(kpi_df)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  )
90
 
91
  if results is not None:
92
+ wcel_analysis_df = results[0]
93
+ kpi_df = results[1]
94
 
95
+ WcelCapacity.final_results = convert_dfs(
96
+ [wcel_analysis_df, kpi_df], ["wcel_analysis", "kpi"]
97
+ )
98
  st.download_button(
99
  on_click="ignore",
100
  type="primary",
 
103
  file_name="WCEL_Capacity_Report.xlsx",
104
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
105
  )
106
+ st.write(wcel_analysis_df)
107
+ # Add dataframe and Bar chart with "final_comments" distribution
108
+ st.markdown("***")
109
+ st.markdown(":blue[**Final comment distribution**]")
110
+ final_comments_df = (
111
+ wcel_analysis_df.groupby("final_comments")
112
+ .size()
113
+ .reset_index(name="count")
114
+ .sort_values(by="count", ascending=False)
115
+ )
116
+ final_comments_col1, final_comments_col2 = st.columns((1, 3))
117
+ with final_comments_col1:
118
+ st.write(final_comments_df)
119
+ with final_comments_col2:
120
+ fig = px.bar(
121
+ final_comments_df,
122
+ x="final_comments",
123
+ y="count",
124
+ title="Final Comments Distribution",
125
+ text="count",
126
+ )
127
+ fig.update_traces(textposition="outside")
128
+ fig.update_layout(height=600)
129
+ st.plotly_chart(fig)
130
+
131
+ # Add dataframe and Pie chart with "operational_comments" distribution
132
+ st.markdown("***")
133
+ st.markdown(":blue[**Operational comment distribution**]")
134
+ operational_comments_df = (
135
+ wcel_analysis_df.groupby("operational_comments")
136
+ .size()
137
+ .reset_index(name="count")
138
+ .sort_values(by="count", ascending=False)
139
+ )
140
+ operational_comments_df["percent"] = (
141
+ operational_comments_df["count"] / operational_comments_df["count"].sum()
142
+ ) * 100
143
+ operational_comments_col1, operational_comments_col2 = st.columns((1, 3))
144
+ with operational_comments_col1:
145
+ st.write(operational_comments_df)
146
+ with operational_comments_col2:
147
+ fig = px.pie(
148
+ operational_comments_df,
149
+ names="operational_comments",
150
+ values="count",
151
+ hover_name="operational_comments",
152
+ hover_data=["count", "percent"],
153
+ title="Operational Comments Distribution",
154
+ )
155
+ fig.update_layout(height=600)
156
+ fig.update_traces(
157
+ texttemplate="<b>%{label}</b><br> %{value} <b>(%{customdata[1]:.1f}%)</b>",
158
+ textfont_size=15,
159
+ textposition="outside",
160
+ )
161
+ st.plotly_chart(fig)
162
+
163
+ # Add dataframe and Bar chart with "operational_comments" distribution per Region
164
+ st.markdown("***")
165
+ st.markdown(":blue[**Operational comment distribution per Region**]")
166
+ operational_comments_df = (
167
+ wcel_analysis_df.groupby(["Region", "operational_comments"])
168
+ .size()
169
+ .reset_index(name="count")
170
+ .sort_values(by="count", ascending=False)
171
+ )
172
+ operational_comments_col1, operational_comments_col2 = st.columns((1, 3))
173
+ with operational_comments_col1:
174
+ st.write(operational_comments_df)
175
+ with operational_comments_col2:
176
+ fig = px.bar(
177
+ operational_comments_df,
178
+ x="Region",
179
+ y="count",
180
+ color="operational_comments",
181
+ title="Operational Comments Distribution per Region",
182
+ text="count",
183
+ )
184
+ fig.update_traces(textposition="outside")
185
+ fig.update_layout(height=600)
186
+ st.plotly_chart(fig)
187
+
188
+ # Add dataframe and Pie chart with "fails_comments" distribution
189
+ st.markdown("***")
190
+ st.markdown(":blue[**Fails comment distribution**]")
191
+ fails_comments_df = (
192
+ wcel_analysis_df.groupby("fails_comments")
193
+ .size()
194
+ .reset_index(name="count")
195
+ .sort_values(by="count", ascending=False)
196
+ )
197
+
198
+ # replace empty strings with "Cell OK"
199
+ fails_comments_df["fails_comments"] = fails_comments_df[
200
+ "fails_comments"
201
+ ].replace("", "Cell OK")
202
+
203
+ fails_comments_df["percent"] = (
204
+ fails_comments_df["count"] / fails_comments_df["count"].sum()
205
+ ) * 100
206
+ fails_comments_col1, fails_comments_col2 = st.columns((1, 3))
207
+ with fails_comments_col1:
208
+ st.write(fails_comments_df)
209
+ with fails_comments_col2:
210
+ fig = px.pie(
211
+ fails_comments_df,
212
+ names="fails_comments",
213
+ values="count",
214
+ hover_name="fails_comments",
215
+ hover_data=["count", "percent"],
216
+ title="Fails Comments Distribution",
217
+ )
218
+ fig.update_layout(height=600)
219
+ fig.update_traces(
220
+ texttemplate="<b>%{label}</b><br> %{value} <b>(%{customdata[1]:.1f}%)</b>",
221
+ textfont_size=15,
222
+ textposition="outside",
223
+ )
224
+ st.plotly_chart(fig)
225
+
226
+ # Add dataframe and Bar chart with "fails_comments" distribution per Region
227
+ st.markdown("***")
228
+ st.markdown(":blue[**Fails comment distribution per Region**]")
229
+ fails_comments_df = (
230
+ wcel_analysis_df.groupby(["Region", "fails_comments"])
231
+ .size()
232
+ .reset_index(name="count")
233
+ .sort_values(by="count", ascending=False)
234
+ )
235
+
236
+ # replace empty strings with "Cell OK"
237
+ fails_comments_df["fails_comments"] = fails_comments_df[
238
+ "fails_comments"
239
+ ].replace("", "Cell OK")
240
+
241
+ fails_comments_col1, fails_comments_col2 = st.columns((1, 3))
242
+ with fails_comments_col1:
243
+ st.write(fails_comments_df)
244
+ with fails_comments_col2:
245
+ fig = px.bar(
246
+ fails_comments_df,
247
+ x="Region",
248
+ y="count",
249
+ color="fails_comments",
250
+ title="Fails Comments Distribution per Region",
251
+ text="count",
252
+ )
253
+ fig.update_traces(textposition="outside", textfont_size=15)
254
+ fig.update_layout(height=600)
255
+ st.plotly_chart(fig)
256
+
257
+ # create a map plot with scatter_map with code ,Longitude,Latitude,fails_comments
258
+ st.markdown("***")
259
+ st.markdown(":blue[**Fails comments distribution**]")
260
+ fails_comments_map_df = wcel_analysis_df[
261
+ ["code", "Longitude", "Latitude", "fails_comments"]
262
+ ].dropna(subset=["code", "Longitude", "Latitude", "fails_comments"])
263
+
264
+ # replace empty strings with "Cell OK"
265
+ fails_comments_map_df["fails_comments"] = fails_comments_map_df[
266
+ "fails_comments"
267
+ ].replace("", "Cell OK")
268
+
269
+ # add size column equalt to 20
270
+ fails_comments_map_df["size"] = 20
271
+
272
+ fig = px.scatter_map(
273
+ fails_comments_map_df,
274
+ lat="Latitude",
275
+ lon="Longitude",
276
+ color="fails_comments",
277
+ size="size",
278
+ zoom=10,
279
+ height=600,
280
+ title="Fails comments distribution",
281
+ hover_data={
282
+ "code": True,
283
+ "fails_comments": True,
284
+ },
285
+ hover_name="code",
286
+ )
287
+ fig.update_layout(mapbox_style="open-street-map")
288
+ st.plotly_chart(fig, use_container_width=True)
289
+
290
+ # create a map plot with scatter_map with code ,Longitude,Latitude,operational_comments
291
+ operational_comments_map_df = wcel_analysis_df[
292
+ ["code", "Longitude", "Latitude", "operational_comments"]
293
+ ].dropna(subset=["code", "Longitude", "Latitude", "operational_comments"])
294
+
295
+ # replace empty strings with "Cell OK"
296
+ operational_comments_map_df["operational_comments"] = (
297
+ operational_comments_map_df["operational_comments"].replace("", "Cell OK")
298
+ )
299
+
300
+ # add size column equalt to 20
301
+ operational_comments_map_df["size"] = 20
302
+
303
+ fig = px.scatter_map(
304
+ operational_comments_map_df,
305
+ lat="Latitude",
306
+ lon="Longitude",
307
+ color="operational_comments",
308
+ size="size",
309
+ zoom=10,
310
+ height=600,
311
+ title="Operational comments distribution",
312
+ hover_data={
313
+ "code": True,
314
+ "operational_comments": True,
315
+ },
316
+ hover_name="code",
317
+ )
318
+ fig.update_layout(mapbox_style="open-street-map")
319
+ st.plotly_chart(fig, use_container_width=True)
process_kpi/process_wcel_capacity.py CHANGED
@@ -9,6 +9,7 @@ from utils.kpi_analysis_utils import (
9
  kpi_naming_cleaning,
10
  summarize_fails_comments,
11
  )
 
12
 
13
  tx_comments_mapping = {
14
  "iub_frameloss exceeded threshold": "iub frameloss",
@@ -31,6 +32,20 @@ operational_comments_mapping = {
31
  "hsdpa iub congestion, critical instability": "Availability and TX issues",
32
  }
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  KPI_COLUMNS = [
35
  "WCEL_name",
36
  "date",
@@ -48,6 +63,36 @@ KPI_COLUMNS = [
48
  "rrc_conn_stp_fail_bts_M1001C4",
49
  ]
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  class WcelCapacity:
53
  final_results: pd.DataFrame = None
@@ -80,13 +125,11 @@ def wcel_kpi_analysis(
80
  hsdpa_user_throughput_df = pivoted_kpi_dfs["HSDPA_USER_THROUGHPUT"]
81
  max_simult_hsdpa_users_df = pivoted_kpi_dfs["Max_simult_HSDPA_users"]
82
  # Add Max of Trafics, throughput and max users
83
- trafic_cs_df["max_traffic_cs"] = trafic_cs_df.max(axis=1)
84
- hsdpa_traffic_df["max_traffic_dl"] = hsdpa_traffic_df.max(axis=1)
85
  hsdpa_user_throughput_df["max_dl_throughput"] = hsdpa_user_throughput_df.max(axis=1)
86
  max_simult_hsdpa_users_df["max_users"] = max_simult_hsdpa_users_df.max(axis=1)
87
  # add average of Trafics, throughput and max users
88
- trafic_cs_df["avg_traffic_cs"] = trafic_cs_df.mean(axis=1)
89
- hsdpa_traffic_df["avg_traffic_dl"] = hsdpa_traffic_df.mean(axis=1)
90
  hsdpa_user_throughput_df["avg_dl_throughput"] = hsdpa_user_throughput_df.mean(
91
  axis=1
92
  )
@@ -196,7 +239,72 @@ def wcel_kpi_analysis(
196
  new_column="fails_comments",
197
  )
198
  kpi_df["fails_comments"] = kpi_df["fails_comments"].apply(summarize_fails_comments)
199
- return [kpi_df]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
 
202
  def load_and_process_wcel_capacity_data(
@@ -228,7 +336,7 @@ def load_and_process_wcel_capacity_data(
228
  df = kpi_naming_cleaning(df)
229
  df = create_daily_date(df)
230
  df = df[KPI_COLUMNS]
231
- df = wcel_kpi_analysis(
232
  df,
233
  num_last_days,
234
  num_threshold_days,
@@ -237,4 +345,4 @@ def load_and_process_wcel_capacity_data(
237
  hsdpa_congestion_rate_iub_threshold,
238
  fails_treshold,
239
  )
240
- return df
 
9
  kpi_naming_cleaning,
10
  summarize_fails_comments,
11
  )
12
+ from utils.utils_vars import get_physical_db
13
 
14
  tx_comments_mapping = {
15
  "iub_frameloss exceeded threshold": "iub frameloss",
 
32
  "hsdpa iub congestion, critical instability": "Availability and TX issues",
33
  }
34
 
35
+ fails_comments_mapping = {
36
+ "ac, ac_dl, bts, code fails": "Power, Bts and Code fails",
37
+ "bts fails": "Bts fails",
38
+ "ac, bts, code fails": "Power and Code fails",
39
+ "ac, code fails": "Power fails",
40
+ "ac fails": "Power fails",
41
+ "ac, ac_dl fails": "Power fails",
42
+ "ac, bts fails": "Power and Bts fails",
43
+ "ac, ac_dl, bts fails": "Power and Bts fails",
44
+ "ac, ac_dl, code fails": "Power and Code fails",
45
+ "ac, ac_ul, bts, code fails": "Power, Bts and Code fails",
46
+ "ac, ac_dl, ac_ul, bts, code fails": "Power, Bts and Code fails",
47
+ }
48
+
49
  KPI_COLUMNS = [
50
  "WCEL_name",
51
  "date",
 
63
  "rrc_conn_stp_fail_bts_M1001C4",
64
  ]
65
 
66
+ WCEL_ANALYSIS_COLUMNS = [
67
+ "WCEL_name",
68
+ "Average_cell_availability_daily",
69
+ "number_of_days_exceeding_availability_threshold_daily",
70
+ "availability_comment_daily",
71
+ "sum_traffic_cs",
72
+ "sum_traffic_dl",
73
+ "max_dl_throughput",
74
+ "avg_dl_throughput",
75
+ "max_users",
76
+ "max_iub_frameloss",
77
+ "number_of_days_with_iub_frameloss_exceeded",
78
+ "max_hsdpa_congestion_rate_iub",
79
+ "number_of_days_with_hsdpa_congestion_rate_iub_exceeded",
80
+ "max_rrc_fail_ac",
81
+ "number_of_days_with_rrc_fail_ac_exceeded",
82
+ "max_rrc_fail_ac_ul",
83
+ "number_of_days_with_rrc_fail_ac_ul_exceeded",
84
+ "max_rrc_fail_ac_dl",
85
+ "number_of_days_with_rrc_fail_ac_dl_exceeded",
86
+ "max_rrc_fail_code",
87
+ "number_of_days_with_rrc_fail_code_exceeded",
88
+ "max_rrc_fail_bts",
89
+ "number_of_days_with_rrc_fail_bts_exceeded",
90
+ "tx_congestion_comments",
91
+ "operational_comments",
92
+ "fails_comments",
93
+ "final_comments",
94
+ ]
95
+
96
 
97
  class WcelCapacity:
98
  final_results: pd.DataFrame = None
 
125
  hsdpa_user_throughput_df = pivoted_kpi_dfs["HSDPA_USER_THROUGHPUT"]
126
  max_simult_hsdpa_users_df = pivoted_kpi_dfs["Max_simult_HSDPA_users"]
127
  # Add Max of Trafics, throughput and max users
128
+ trafic_cs_df["sum_traffic_cs"] = trafic_cs_df.sum(axis=1)
129
+ hsdpa_traffic_df["sum_traffic_dl"] = hsdpa_traffic_df.sum(axis=1)
130
  hsdpa_user_throughput_df["max_dl_throughput"] = hsdpa_user_throughput_df.max(axis=1)
131
  max_simult_hsdpa_users_df["max_users"] = max_simult_hsdpa_users_df.max(axis=1)
132
  # add average of Trafics, throughput and max users
 
 
133
  hsdpa_user_throughput_df["avg_dl_throughput"] = hsdpa_user_throughput_df.mean(
134
  axis=1
135
  )
 
239
  new_column="fails_comments",
240
  )
241
  kpi_df["fails_comments"] = kpi_df["fails_comments"].apply(summarize_fails_comments)
242
+ kpi_df["fails_comments"] = kpi_df["fails_comments"].apply(
243
+ lambda x: fails_comments_mapping.get(x, x)
244
+ )
245
+ kpi_df = combine_comments(
246
+ kpi_df,
247
+ "operational_comments",
248
+ "fails_comments",
249
+ new_column="final_comments",
250
+ )
251
+
252
+ wcel_analysis_df = kpi_df[WCEL_ANALYSIS_COLUMNS]
253
+ wcel_analysis_df = wcel_analysis_df.droplevel(level=1, axis=1)
254
+
255
+ # Rename
256
+ wcel_analysis_df = wcel_analysis_df.rename(
257
+ columns={
258
+ "WCEL_name": "name",
259
+ "Average_cell_availability_daily": "Avg_availability",
260
+ "number_of_days_exceeding_availability_threshold_daily": "Avail_exceed_days",
261
+ "availability_comment_daily": "availability_comment",
262
+ "number_of_days_with_iub_frameloss_exceeded": "iub_frameloss_exceed_days",
263
+ "number_of_days_with_hsdpa_congestion_rate_iub_exceeded": "hsdpa_iub_exceed_days",
264
+ "number_of_days_with_rrc_fail_ac_exceeded": "ac_fail_exceed_days",
265
+ "number_of_days_with_rrc_fail_ac_ul_exceeded": "ac_ul_fail_exceed_days",
266
+ "number_of_days_with_rrc_fail_ac_dl_exceeded": "ac_dl_fail_exceed_days",
267
+ "number_of_days_with_rrc_fail_code_exceeded": "code_fail_exceed_days",
268
+ "number_of_days_with_rrc_fail_bts_exceeded": "bts_fail_exceed_days",
269
+ }
270
+ )
271
+ # remove row if name less than 5 characters
272
+ wcel_analysis_df = wcel_analysis_df[wcel_analysis_df["name"].str.len() >= 5]
273
+
274
+ wcel_analysis_df["code"] = wcel_analysis_df["name"].str.split("_").str[0]
275
+ wcel_analysis_df["code"] = (
276
+ pd.to_numeric(wcel_analysis_df["code"], errors="coerce").fillna(0).astype(int)
277
+ )
278
+ wcel_analysis_df["Region"] = wcel_analysis_df["name"].str.split("_").str[1]
279
+ # move code to the first column
280
+ wcel_analysis_df = wcel_analysis_df[
281
+ ["code", "Region"]
282
+ + [col for col in wcel_analysis_df if col != "code" and col != "Region"]
283
+ ]
284
+
285
+ # Load physical database
286
+ physical_db: pd.DataFrame = get_physical_db()
287
+
288
+ # Convert code_sector to code
289
+ physical_db["code"] = physical_db["Code_Sector"].str.split("_").str[0]
290
+ # remove duplicates
291
+ physical_db = physical_db.drop_duplicates(subset="code")
292
+
293
+ # keep only code and longitude and latitude
294
+ physical_db = physical_db[["code", "Longitude", "Latitude"]]
295
+
296
+ physical_db["code"] = (
297
+ pd.to_numeric(physical_db["code"], errors="coerce").fillna(0).astype(int)
298
+ )
299
+
300
+ wcel_analysis_df = pd.merge(
301
+ wcel_analysis_df,
302
+ physical_db,
303
+ on="code",
304
+ how="left",
305
+ )
306
+
307
+ return [wcel_analysis_df, kpi_df]
308
 
309
 
310
  def load_and_process_wcel_capacity_data(
 
336
  df = kpi_naming_cleaning(df)
337
  df = create_daily_date(df)
338
  df = df[KPI_COLUMNS]
339
+ dfs = wcel_kpi_analysis(
340
  df,
341
  num_last_days,
342
  num_threshold_days,
 
345
  hsdpa_congestion_rate_iub_threshold,
346
  fails_treshold,
347
  )
348
+ return dfs