Add city-level traffic and availability drill-down with daily aggregation and SLA comparison across all RATs
Browse files
apps/kpi_analysis/trafic_analysis.py
CHANGED
|
@@ -1229,6 +1229,105 @@ if "full_df" in st.session_state:
|
|
| 1229 |
degraded_site_df = pd.DataFrame(degraded_rows_site)
|
| 1230 |
st.dataframe(degraded_site_df.round(2))
|
| 1231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1232 |
# Temporal availability analysis - daily averages per RAT
|
| 1233 |
if any(
|
| 1234 |
col in analysis_df.columns
|
|
|
|
| 1229 |
degraded_site_df = pd.DataFrame(degraded_rows_site)
|
| 1230 |
st.dataframe(degraded_site_df.round(2))
|
| 1231 |
|
| 1232 |
+
if "City" in analysis_df.columns and analysis_df["City"].notna().any():
|
| 1233 |
+
st.subheader("City drill-down: traffic and availability over time")
|
| 1234 |
+
cities_df = (
|
| 1235 |
+
analysis_df[["City"]].dropna().drop_duplicates().sort_values(by="City")
|
| 1236 |
+
)
|
| 1237 |
+
selected_city = st.selectbox(
|
| 1238 |
+
"Select a City for aggregated view",
|
| 1239 |
+
options=cities_df["City"].tolist(),
|
| 1240 |
+
)
|
| 1241 |
+
city_detail_df = analysis_df[analysis_df["City"] == selected_city].copy()
|
| 1242 |
+
if not city_detail_df.empty:
|
| 1243 |
+
city_detail_df = city_detail_df.sort_values("date")
|
| 1244 |
+
traffic_cols_city = [
|
| 1245 |
+
col
|
| 1246 |
+
for col in ["total_voice_trafic", "total_data_trafic"]
|
| 1247 |
+
if col in city_detail_df.columns
|
| 1248 |
+
]
|
| 1249 |
+
if traffic_cols_city:
|
| 1250 |
+
city_traffic = (
|
| 1251 |
+
city_detail_df.groupby("date")[traffic_cols_city]
|
| 1252 |
+
.sum()
|
| 1253 |
+
.reset_index()
|
| 1254 |
+
)
|
| 1255 |
+
traffic_long_city = city_traffic.melt(
|
| 1256 |
+
id_vars="date",
|
| 1257 |
+
value_vars=traffic_cols_city,
|
| 1258 |
+
var_name="metric",
|
| 1259 |
+
value_name="value",
|
| 1260 |
+
)
|
| 1261 |
+
fig_traffic_city = px.line(
|
| 1262 |
+
traffic_long_city,
|
| 1263 |
+
x="date",
|
| 1264 |
+
y="value",
|
| 1265 |
+
color="metric",
|
| 1266 |
+
)
|
| 1267 |
+
st.plotly_chart(
|
| 1268 |
+
fig_traffic_city,
|
| 1269 |
+
key=f"traffic_city_{selected_city}",
|
| 1270 |
+
)
|
| 1271 |
+
|
| 1272 |
+
avail_cols_city = []
|
| 1273 |
+
rename_map_city = {}
|
| 1274 |
+
if "2g_tch_avail" in city_detail_df.columns:
|
| 1275 |
+
avail_cols_city.append("2g_tch_avail")
|
| 1276 |
+
rename_map_city["2g_tch_avail"] = "2G"
|
| 1277 |
+
if "3g_cell_avail" in city_detail_df.columns:
|
| 1278 |
+
avail_cols_city.append("3g_cell_avail")
|
| 1279 |
+
rename_map_city["3g_cell_avail"] = "3G"
|
| 1280 |
+
if "lte_cell_avail" in city_detail_df.columns:
|
| 1281 |
+
avail_cols_city.append("lte_cell_avail")
|
| 1282 |
+
rename_map_city["lte_cell_avail"] = "LTE"
|
| 1283 |
+
if avail_cols_city:
|
| 1284 |
+
avail_city_df = city_detail_df[["date"] + avail_cols_city].copy()
|
| 1285 |
+
avail_city_df = avail_city_df.rename(columns=rename_map_city)
|
| 1286 |
+
value_cols_city = [c for c in avail_city_df.columns if c != "date"]
|
| 1287 |
+
avail_long_city = avail_city_df.melt(
|
| 1288 |
+
id_vars="date",
|
| 1289 |
+
value_vars=value_cols_city,
|
| 1290 |
+
var_name="RAT",
|
| 1291 |
+
value_name="availability",
|
| 1292 |
+
)
|
| 1293 |
+
fig_avail_city = px.line(
|
| 1294 |
+
avail_long_city,
|
| 1295 |
+
x="date",
|
| 1296 |
+
y="availability",
|
| 1297 |
+
color="RAT",
|
| 1298 |
+
)
|
| 1299 |
+
st.plotly_chart(
|
| 1300 |
+
fig_avail_city,
|
| 1301 |
+
key=f"avail_city_{selected_city}",
|
| 1302 |
+
)
|
| 1303 |
+
|
| 1304 |
+
city_detail_df["date_only"] = city_detail_df["date"].dt.date
|
| 1305 |
+
degraded_rows_city = []
|
| 1306 |
+
for rat_col, rat_name, sla_value in [
|
| 1307 |
+
("2g_tch_avail", "2G", sla_2g),
|
| 1308 |
+
("3g_cell_avail", "3G", sla_3g),
|
| 1309 |
+
("lte_cell_avail", "LTE", sla_lte),
|
| 1310 |
+
]:
|
| 1311 |
+
if rat_col in city_detail_df.columns:
|
| 1312 |
+
daily_city = (
|
| 1313 |
+
city_detail_df.groupby("date_only")[rat_col]
|
| 1314 |
+
.mean()
|
| 1315 |
+
.dropna()
|
| 1316 |
+
)
|
| 1317 |
+
mask_city = daily_city < sla_value
|
| 1318 |
+
for d, val in daily_city[mask_city].items():
|
| 1319 |
+
degraded_rows_city.append(
|
| 1320 |
+
{
|
| 1321 |
+
"RAT": rat_name,
|
| 1322 |
+
"date": d,
|
| 1323 |
+
"avg_availability": val,
|
| 1324 |
+
"SLA": sla_value,
|
| 1325 |
+
}
|
| 1326 |
+
)
|
| 1327 |
+
if degraded_rows_city:
|
| 1328 |
+
degraded_city_df = pd.DataFrame(degraded_rows_city)
|
| 1329 |
+
st.dataframe(degraded_city_df.round(2))
|
| 1330 |
+
|
| 1331 |
# Temporal availability analysis - daily averages per RAT
|
| 1332 |
if any(
|
| 1333 |
col in analysis_df.columns
|