add avail and Abis checking BH
Browse files
apps/kpi_analysis/gsm_capacity.py
CHANGED
@@ -135,7 +135,7 @@ if (
|
|
135 |
gsm_analysis_df.groupby("Final comment").size().reset_index(name="count")
|
136 |
)
|
137 |
fig = px.bar(final_comments_df, x="Final comment", y="count")
|
138 |
-
fig.update_layout(height=
|
139 |
fig.update_traces(texttemplate="%{value}", textposition="outside")
|
140 |
st.plotly_chart(fig, use_container_width=True)
|
141 |
st.write(final_comments_df)
|
@@ -147,7 +147,7 @@ if (
|
|
147 |
.reset_index(name="count")
|
148 |
)
|
149 |
fig = px.bar(bh_congestion_status_df, x="BH Congestion status", y="count")
|
150 |
-
fig.update_layout(height=
|
151 |
fig.update_traces(texttemplate="%{value}", textposition="outside")
|
152 |
st.plotly_chart(fig, use_container_width=True)
|
153 |
st.write(bh_congestion_status_df)
|
@@ -158,7 +158,7 @@ if (
|
|
158 |
.reset_index(name="count")
|
159 |
)
|
160 |
fig = px.bar(operational_comments_df, x="operational_comment", y="count")
|
161 |
-
fig.update_layout(height=
|
162 |
fig.update_traces(texttemplate="%{value}", textposition="outside")
|
163 |
st.plotly_chart(fig, use_container_width=True)
|
164 |
st.write(operational_comments_df)
|
|
|
135 |
gsm_analysis_df.groupby("Final comment").size().reset_index(name="count")
|
136 |
)
|
137 |
fig = px.bar(final_comments_df, x="Final comment", y="count")
|
138 |
+
fig.update_layout(height=1000)
|
139 |
fig.update_traces(texttemplate="%{value}", textposition="outside")
|
140 |
st.plotly_chart(fig, use_container_width=True)
|
141 |
st.write(final_comments_df)
|
|
|
147 |
.reset_index(name="count")
|
148 |
)
|
149 |
fig = px.bar(bh_congestion_status_df, x="BH Congestion status", y="count")
|
150 |
+
fig.update_layout(height=800)
|
151 |
fig.update_traces(texttemplate="%{value}", textposition="outside")
|
152 |
st.plotly_chart(fig, use_container_width=True)
|
153 |
st.write(bh_congestion_status_df)
|
|
|
158 |
.reset_index(name="count")
|
159 |
)
|
160 |
fig = px.bar(operational_comments_df, x="operational_comment", y="count")
|
161 |
+
fig.update_layout(height=600)
|
162 |
fig.update_traces(texttemplate="%{value}", textposition="outside")
|
163 |
st.plotly_chart(fig, use_container_width=True)
|
164 |
st.write(operational_comments_df)
|
process_kpi/process_gsm_capacity.py
CHANGED
@@ -74,19 +74,26 @@ BH_COLUMNS_FOR_CAPACITY = [
|
|
74 |
"max_tch_call_blocking_bh",
|
75 |
"avg_tch_call_blocking_bh",
|
76 |
"number_of_days_with_tch_blocking_exceeded_bh",
|
|
|
77 |
"max_sdcch_real_blocking_bh",
|
78 |
"avg_sdcch_real_blocking_bh",
|
79 |
"number_of_days_with_sdcch_blocking_exceeded_bh",
|
80 |
-
"tch_call_blocking_bh_comment",
|
81 |
"sdcch_real_blocking_bh_comment",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
]
|
83 |
|
84 |
DAILY_COLUMNS_FOR_CAPACITY = [
|
85 |
-
"
|
86 |
-
"
|
87 |
-
"
|
88 |
-
"avg_tch_abis_fail_daily",
|
89 |
"max_tch_abis_fail_daily",
|
|
|
90 |
"number_of_days_with_tch_abis_fail_exceeded_daily",
|
91 |
"tch_abis_fail_daily_comment",
|
92 |
]
|
@@ -112,6 +119,8 @@ def bh_dfs_per_kpi(
|
|
112 |
tch_blocking_threshold: int = 0.50,
|
113 |
sdcch_blocking_threshold: int = 0.50,
|
114 |
number_of_threshold_days: int = 3,
|
|
|
|
|
115 |
) -> pd.DataFrame:
|
116 |
"""
|
117 |
Create pivoted DataFrames for each KPI and perform analysis.
|
@@ -138,6 +147,7 @@ def bh_dfs_per_kpi(
|
|
138 |
sdcch_real_blocking_df: pd.DataFrame = pivoted_kpi_dfs["SDCCH_real_blocking"]
|
139 |
Carried_Traffic_df: pd.DataFrame = pivoted_kpi_dfs["2G_Carried_Traffic"]
|
140 |
tch_availability_ratio_df: pd.DataFrame = pivoted_kpi_dfs["TCH_availability_ratio"]
|
|
|
141 |
|
142 |
# ANALISYS
|
143 |
|
@@ -162,12 +172,27 @@ def bh_dfs_per_kpi(
|
|
162 |
number_of_kpi_days=number_of_kpi_days,
|
163 |
)
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
bh_kpi_df = pd.concat(
|
166 |
[
|
167 |
-
tch_availability_ratio_df,
|
168 |
Carried_Traffic_df,
|
169 |
tch_call_blocking_df,
|
170 |
sdcch_real_blocking_df,
|
|
|
|
|
171 |
],
|
172 |
axis=1,
|
173 |
)
|
@@ -180,6 +205,8 @@ def analyse_bh_data(
|
|
180 |
tch_blocking_threshold: int,
|
181 |
sdcch_blocking_threshold: int,
|
182 |
number_of_threshold_days: int,
|
|
|
|
|
183 |
) -> pd.DataFrame:
|
184 |
df = pd.read_csv(bh_report_path, delimiter=";")
|
185 |
df = kpi_naming_cleaning(df)
|
@@ -191,6 +218,8 @@ def analyse_bh_data(
|
|
191 |
tch_blocking_threshold=tch_blocking_threshold,
|
192 |
sdcch_blocking_threshold=sdcch_blocking_threshold,
|
193 |
number_of_threshold_days=number_of_threshold_days,
|
|
|
|
|
194 |
)
|
195 |
|
196 |
bh_df_for_capacity = df.copy()
|
@@ -287,7 +316,7 @@ def daily_dfs_per_kpi(
|
|
287 |
|
288 |
daily_kpi_df = combine_comments(
|
289 |
daily_kpi_df,
|
290 |
-
"
|
291 |
"tch_abis_fail_daily_comment",
|
292 |
"sdcch_real_blocking_daily_comment",
|
293 |
new_column="sdcch_comments",
|
@@ -295,7 +324,7 @@ def daily_dfs_per_kpi(
|
|
295 |
|
296 |
daily_kpi_df = combine_comments(
|
297 |
daily_kpi_df,
|
298 |
-
"
|
299 |
"tch_abis_fail_daily_comment",
|
300 |
"tch_call_blocking_daily_comment",
|
301 |
new_column="tch_comments",
|
@@ -410,6 +439,8 @@ def analyze_gsm_data(
|
|
410 |
tch_blocking_threshold=tch_blocking_threshold,
|
411 |
sdcch_blocking_threshold=sdcch_blocking_threshold,
|
412 |
number_of_threshold_days=number_of_threshold_days,
|
|
|
|
|
413 |
)
|
414 |
|
415 |
bh_kpi_df = bh_kpi_dfs[0]
|
@@ -471,22 +502,22 @@ def analyze_gsm_data(
|
|
471 |
gsm_analysis_df["Target TRXs"] - gsm_analysis_df["number_trx_per_cell"]
|
472 |
)
|
473 |
|
474 |
-
# if "
|
475 |
-
# if "
|
476 |
-
# if "
|
477 |
-
# if "
|
478 |
# Else "Operational is OK"
|
479 |
gsm_analysis_df["operational_comment"] = np.select(
|
480 |
[
|
481 |
-
gsm_analysis_df["
|
482 |
-
(gsm_analysis_df["
|
483 |
& (
|
484 |
gsm_analysis_df["tch_abis_fail_daily_comment"]
|
485 |
== "tch abis fail exceeded threshold"
|
486 |
), # 2
|
487 |
-
(gsm_analysis_df["
|
488 |
& pd.isna(gsm_analysis_df["tch_abis_fail_daily_comment"]), # 3
|
489 |
-
(gsm_analysis_df["
|
490 |
& (
|
491 |
gsm_analysis_df["tch_abis_fail_daily_comment"]
|
492 |
== "tch abis fail exceeded threshold"
|
|
|
74 |
"max_tch_call_blocking_bh",
|
75 |
"avg_tch_call_blocking_bh",
|
76 |
"number_of_days_with_tch_blocking_exceeded_bh",
|
77 |
+
"tch_call_blocking_bh_comment",
|
78 |
"max_sdcch_real_blocking_bh",
|
79 |
"avg_sdcch_real_blocking_bh",
|
80 |
"number_of_days_with_sdcch_blocking_exceeded_bh",
|
|
|
81 |
"sdcch_real_blocking_bh_comment",
|
82 |
+
"Average_cell_availability_bh",
|
83 |
+
"number_of_days_exceeding_availability_threshold_bh",
|
84 |
+
"availability_comment_bh",
|
85 |
+
"max_tch_abis_fail_bh",
|
86 |
+
"avg_tch_abis_fail_bh",
|
87 |
+
"number_of_days_with_tch_abis_fail_exceeded_bh",
|
88 |
+
"tch_abis_fail_bh_comment",
|
89 |
]
|
90 |
|
91 |
DAILY_COLUMNS_FOR_CAPACITY = [
|
92 |
+
"Average_cell_availability_daily",
|
93 |
+
"number_of_days_exceeding_availability_threshold_daily",
|
94 |
+
"availability_comment_daily",
|
|
|
95 |
"max_tch_abis_fail_daily",
|
96 |
+
"avg_tch_abis_fail_daily",
|
97 |
"number_of_days_with_tch_abis_fail_exceeded_daily",
|
98 |
"tch_abis_fail_daily_comment",
|
99 |
]
|
|
|
119 |
tch_blocking_threshold: int = 0.50,
|
120 |
sdcch_blocking_threshold: int = 0.50,
|
121 |
number_of_threshold_days: int = 3,
|
122 |
+
tch_abis_fails_threshold: int = 10,
|
123 |
+
availability_threshold: int = 95,
|
124 |
) -> pd.DataFrame:
|
125 |
"""
|
126 |
Create pivoted DataFrames for each KPI and perform analysis.
|
|
|
147 |
sdcch_real_blocking_df: pd.DataFrame = pivoted_kpi_dfs["SDCCH_real_blocking"]
|
148 |
Carried_Traffic_df: pd.DataFrame = pivoted_kpi_dfs["2G_Carried_Traffic"]
|
149 |
tch_availability_ratio_df: pd.DataFrame = pivoted_kpi_dfs["TCH_availability_ratio"]
|
150 |
+
tch_abis_fails_df: pd.DataFrame = pivoted_kpi_dfs["TCH_ABIS_FAIL_CALL_c001084"]
|
151 |
|
152 |
# ANALISYS
|
153 |
|
|
|
172 |
number_of_kpi_days=number_of_kpi_days,
|
173 |
)
|
174 |
|
175 |
+
tch_abis_fails_df = analyze_tch_abis_fails(
|
176 |
+
df=tch_abis_fails_df,
|
177 |
+
number_of_kpi_days=number_of_kpi_days,
|
178 |
+
tch_abis_fails_threshold=tch_abis_fails_threshold,
|
179 |
+
number_of_threshold_days=number_of_threshold_days,
|
180 |
+
analysis_type="BH",
|
181 |
+
)
|
182 |
+
tch_availability_ratio_df = cell_availability_analysis(
|
183 |
+
df=tch_availability_ratio_df,
|
184 |
+
days=number_of_kpi_days,
|
185 |
+
availability_threshold=availability_threshold,
|
186 |
+
analysis_type="BH",
|
187 |
+
)
|
188 |
+
|
189 |
bh_kpi_df = pd.concat(
|
190 |
[
|
|
|
191 |
Carried_Traffic_df,
|
192 |
tch_call_blocking_df,
|
193 |
sdcch_real_blocking_df,
|
194 |
+
tch_availability_ratio_df,
|
195 |
+
tch_abis_fails_df,
|
196 |
],
|
197 |
axis=1,
|
198 |
)
|
|
|
205 |
tch_blocking_threshold: int,
|
206 |
sdcch_blocking_threshold: int,
|
207 |
number_of_threshold_days: int,
|
208 |
+
tch_abis_fails_threshold: int,
|
209 |
+
availability_threshold: int,
|
210 |
) -> pd.DataFrame:
|
211 |
df = pd.read_csv(bh_report_path, delimiter=";")
|
212 |
df = kpi_naming_cleaning(df)
|
|
|
218 |
tch_blocking_threshold=tch_blocking_threshold,
|
219 |
sdcch_blocking_threshold=sdcch_blocking_threshold,
|
220 |
number_of_threshold_days=number_of_threshold_days,
|
221 |
+
tch_abis_fails_threshold=tch_abis_fails_threshold,
|
222 |
+
availability_threshold=availability_threshold,
|
223 |
)
|
224 |
|
225 |
bh_df_for_capacity = df.copy()
|
|
|
316 |
|
317 |
daily_kpi_df = combine_comments(
|
318 |
daily_kpi_df,
|
319 |
+
"availability_comment_daily",
|
320 |
"tch_abis_fail_daily_comment",
|
321 |
"sdcch_real_blocking_daily_comment",
|
322 |
new_column="sdcch_comments",
|
|
|
324 |
|
325 |
daily_kpi_df = combine_comments(
|
326 |
daily_kpi_df,
|
327 |
+
"availability_comment_daily",
|
328 |
"tch_abis_fail_daily_comment",
|
329 |
"tch_call_blocking_daily_comment",
|
330 |
new_column="tch_comments",
|
|
|
439 |
tch_blocking_threshold=tch_blocking_threshold,
|
440 |
sdcch_blocking_threshold=sdcch_blocking_threshold,
|
441 |
number_of_threshold_days=number_of_threshold_days,
|
442 |
+
tch_abis_fails_threshold=tch_abis_fails_threshold,
|
443 |
+
availability_threshold=availability_threshold,
|
444 |
)
|
445 |
|
446 |
bh_kpi_df = bh_kpi_dfs[0]
|
|
|
502 |
gsm_analysis_df["Target TRXs"] - gsm_analysis_df["number_trx_per_cell"]
|
503 |
)
|
504 |
|
505 |
+
# if "availability_comment_daily" equal to "Down Site" then "Down Site"
|
506 |
+
# if "availability_comment_daily" is not "Availability OK" and "tch_abis_fail_daily_comment" equal to "tch abis fail exceeded threshold" then "Availability and TX issues"
|
507 |
+
# if "availability_comment_daily" is not "Availability OK" and "tch_abis_fail_daily_comment" is empty then "Availability issues"
|
508 |
+
# if "availability_comment_daily" is "Availability OK" and "tch_abis_fail_daily_comment" equal to "tch abis fail exceeded threshold" then "TX issues"
|
509 |
# Else "Operational is OK"
|
510 |
gsm_analysis_df["operational_comment"] = np.select(
|
511 |
[
|
512 |
+
gsm_analysis_df["availability_comment_daily"] == "Down Site", # 1
|
513 |
+
(gsm_analysis_df["availability_comment_daily"] != "Availability OK")
|
514 |
& (
|
515 |
gsm_analysis_df["tch_abis_fail_daily_comment"]
|
516 |
== "tch abis fail exceeded threshold"
|
517 |
), # 2
|
518 |
+
(gsm_analysis_df["availability_comment_daily"] != "Availability OK")
|
519 |
& pd.isna(gsm_analysis_df["tch_abis_fail_daily_comment"]), # 3
|
520 |
+
(gsm_analysis_df["availability_comment_daily"] == "Availability OK")
|
521 |
& (
|
522 |
gsm_analysis_df["tch_abis_fail_daily_comment"]
|
523 |
== "tch abis fail exceeded threshold"
|
process_kpi/process_wbts_capacity.py
CHANGED
@@ -173,7 +173,7 @@ def bb_comments_analysis(df: pd.DataFrame) -> pd.DataFrame:
|
|
173 |
df,
|
174 |
"num_bb_subunits_comment",
|
175 |
"Average_used_bb_ratio_comment",
|
176 |
-
"
|
177 |
new_column="bb_comments",
|
178 |
)
|
179 |
|
@@ -192,7 +192,7 @@ def ce_comments_analysis(df: pd.DataFrame) -> pd.DataFrame:
|
|
192 |
df,
|
193 |
"avail_ce_comment",
|
194 |
"Average_used_ce_ratio_comment",
|
195 |
-
"
|
196 |
new_column="ce_comments",
|
197 |
)
|
198 |
|
|
|
173 |
df,
|
174 |
"num_bb_subunits_comment",
|
175 |
"Average_used_bb_ratio_comment",
|
176 |
+
"availability_comment_daily",
|
177 |
new_column="bb_comments",
|
178 |
)
|
179 |
|
|
|
192 |
df,
|
193 |
"avail_ce_comment",
|
194 |
"Average_used_ce_ratio_comment",
|
195 |
+
"availability_comment_daily",
|
196 |
new_column="ce_comments",
|
197 |
)
|
198 |
|
utils/kpi_analysis_utils.py
CHANGED
@@ -348,7 +348,10 @@ def create_dfs_per_kpi(
|
|
348 |
|
349 |
|
350 |
def cell_availability_analysis(
|
351 |
-
df: pd.DataFrame,
|
|
|
|
|
|
|
352 |
) -> pd.DataFrame:
|
353 |
"""
|
354 |
Analyze cell availability and categorize sites based on availability metrics.
|
@@ -360,12 +363,16 @@ def cell_availability_analysis(
|
|
360 |
Returns:
|
361 |
DataFrame with availability analysis and site status comments
|
362 |
"""
|
363 |
-
result_df = df.copy().fillna(0)
|
364 |
-
last_days_df = result_df.iloc[:, -days:]
|
365 |
-
result_df["
|
|
|
|
|
366 |
|
367 |
# Count the number of days above threshold
|
368 |
-
result_df[
|
|
|
|
|
369 |
lambda row: sum(1 for x in row if x <= availability_threshold), axis=1
|
370 |
)
|
371 |
|
@@ -380,9 +387,9 @@ def cell_availability_analysis(
|
|
380 |
else:
|
381 |
return "Availability OK"
|
382 |
|
383 |
-
result_df["
|
384 |
-
|
385 |
-
)
|
386 |
|
387 |
return result_df
|
388 |
|
@@ -395,7 +402,7 @@ def analyze_tch_abis_fails(
|
|
395 |
tch_abis_fails_threshold: int,
|
396 |
) -> pd.DataFrame:
|
397 |
|
398 |
-
result_df = df.copy()
|
399 |
last_days_df: pd.DataFrame = result_df.iloc[:, -number_of_kpi_days:]
|
400 |
# last_days_df = last_days_df.fillna(0)
|
401 |
|
|
|
348 |
|
349 |
|
350 |
def cell_availability_analysis(
|
351 |
+
df: pd.DataFrame,
|
352 |
+
days: int = 7,
|
353 |
+
availability_threshold: int = 95,
|
354 |
+
analysis_type: str = "daily",
|
355 |
) -> pd.DataFrame:
|
356 |
"""
|
357 |
Analyze cell availability and categorize sites based on availability metrics.
|
|
|
363 |
Returns:
|
364 |
DataFrame with availability analysis and site status comments
|
365 |
"""
|
366 |
+
result_df: pd.DataFrame = df.copy().fillna(0)
|
367 |
+
last_days_df: pd.DataFrame = result_df.iloc[:, -days:]
|
368 |
+
result_df[f"Average_cell_availability_{analysis_type.lower()}"] = last_days_df.mean(
|
369 |
+
axis=1
|
370 |
+
).round(2)
|
371 |
|
372 |
# Count the number of days above threshold
|
373 |
+
result_df[
|
374 |
+
f"number_of_days_exceeding_availability_threshold_{analysis_type.lower()}"
|
375 |
+
] = last_days_df.apply(
|
376 |
lambda row: sum(1 for x in row if x <= availability_threshold), axis=1
|
377 |
)
|
378 |
|
|
|
387 |
else:
|
388 |
return "Availability OK"
|
389 |
|
390 |
+
result_df[f"availability_comment_{analysis_type.lower()}"] = result_df[
|
391 |
+
f"Average_cell_availability_{analysis_type.lower()}"
|
392 |
+
].apply(categorize_availability)
|
393 |
|
394 |
return result_df
|
395 |
|
|
|
402 |
tch_abis_fails_threshold: int,
|
403 |
) -> pd.DataFrame:
|
404 |
|
405 |
+
result_df: pd.DataFrame = df.copy()
|
406 |
last_days_df: pd.DataFrame = result_df.iloc[:, -number_of_kpi_days:]
|
407 |
# last_days_df = last_days_df.fillna(0)
|
408 |
|