Skip to content

Commit a7884ef

Browse files
committed
Merge branch 'feat/better-metric-failure-handling'
2 parents 59fc796 + dead3bd commit a7884ef

File tree

4 files changed

+100
-44
lines changed

4 files changed

+100
-44
lines changed

nannyml/stats/avg/calculator.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,29 @@ def _calculate(self, data: pd.DataFrame, *args, **kwargs) -> Result:
192192

193193
def _calculate_for_column(self, data: pd.DataFrame, column_name: str) -> Dict[str, Any]:
194194
result = {}
195-
value = _calculate_avg_value_stats(data[column_name])
196-
result['value'] = value
197-
result['sampling_error'] = self._sampling_error_components[column_name] / np.sqrt(data.shape[0])
198-
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
199-
result['lower_confidence_boundary'] = result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error']
200-
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
201-
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
202-
result['alert'] = _add_alert_flag(result)
203-
return result
195+
try:
196+
value = _calculate_avg_value_stats(data[column_name])
197+
result['value'] = value
198+
result['sampling_error'] = self._sampling_error_components[column_name] / np.sqrt(data.shape[0])
199+
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
200+
result['lower_confidence_boundary'] = result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error']
201+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
202+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
203+
result['alert'] = _add_alert_flag(result)
204+
except Exception as exc:
205+
if self._logger:
206+
self._logger.error(
207+
f"an unexpected exception occurred during calculation of column '{column_name}': " f"{exc}"
208+
)
209+
result['value'] = np.NaN
210+
result['sampling_error'] = np.NaN
211+
result['upper_confidence_boundary'] = np.NaN
212+
result['lower_confidence_boundary'] = np.NaN
213+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
214+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
215+
result['alert'] = np.NaN
216+
finally:
217+
return result
204218

205219

206220
def _create_multilevel_index(

nannyml/stats/median/calculator.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -196,18 +196,32 @@ def _calculate(self, data: pd.DataFrame, *args, **kwargs) -> Result:
196196

197197
def _calculate_for_column(self, data: pd.DataFrame, column_name: str) -> Dict[str, Any]:
198198
result = {}
199-
value = _calculate_median_value_stats(data[column_name])
200-
result['value'] = value
201-
result['sampling_error'] = summary_stats_median_sampling_error(
202-
self._sampling_error_components[column_name], data[column_name]
203-
)
204-
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
205-
result['lower_confidence_boundary'] = result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error']
206-
207-
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
208-
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
209-
result['alert'] = _add_alert_flag(result)
210-
return result
199+
try:
200+
value = _calculate_median_value_stats(data[column_name])
201+
result['value'] = value
202+
result['sampling_error'] = summary_stats_median_sampling_error(
203+
self._sampling_error_components[column_name], data[column_name]
204+
)
205+
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
206+
result['lower_confidence_boundary'] = result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error']
207+
208+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
209+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
210+
result['alert'] = _add_alert_flag(result)
211+
except Exception as exc:
212+
if self._logger:
213+
self._logger.error(
214+
f"an unexpected exception occurred during calculation of column '{column_name}': " f"{exc}"
215+
)
216+
result['value'] = np.NaN
217+
result['sampling_error'] = np.NaN
218+
result['upper_confidence_boundary'] = np.NaN
219+
result['lower_confidence_boundary'] = np.NaN
220+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
221+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
222+
result['alert'] = np.NaN
223+
finally:
224+
return result
211225

212226

213227
def _create_multilevel_index(

nannyml/stats/std/calculator.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -197,21 +197,35 @@ def _calculate(self, data: pd.DataFrame, *args, **kwargs) -> Result:
197197

198198
def _calculate_for_column(self, data: pd.DataFrame, column_name: str) -> Dict[str, Any]:
199199
result = {}
200-
value = _calculate_std_value_stats(data[column_name])
201-
result['value'] = value
202-
result['sampling_error'] = summary_stats_std_sampling_error(
203-
self._sampling_error_components[column_name], data[column_name]
204-
)
205-
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
206-
result['lower_confidence_boundary'] = np.maximum(
207-
result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error'],
208-
-np.inf if self.lower_threshold_value_limit is None else self.lower_threshold_value_limit
209-
)
200+
try:
201+
value = _calculate_std_value_stats(data[column_name])
202+
result['value'] = value
203+
result['sampling_error'] = summary_stats_std_sampling_error(
204+
self._sampling_error_components[column_name], data[column_name]
205+
)
206+
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
207+
result['lower_confidence_boundary'] = np.maximum(
208+
result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error'],
209+
-np.inf if self.lower_threshold_value_limit is None else self.lower_threshold_value_limit,
210+
)
210211

211-
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
212-
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
213-
result['alert'] = _add_alert_flag(result)
214-
return result
212+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
213+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
214+
result['alert'] = _add_alert_flag(result)
215+
except Exception as exc:
216+
if self._logger:
217+
self._logger.error(
218+
f"an unexpected exception occurred during calculation of column '{column_name}': " f"{exc}"
219+
)
220+
result['value'] = np.NaN
221+
result['sampling_error'] = np.NaN
222+
result['upper_confidence_boundary'] = np.NaN
223+
result['lower_confidence_boundary'] = np.NaN
224+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
225+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
226+
result['alert'] = np.NaN
227+
finally:
228+
return result
215229

216230

217231
def _create_multilevel_index(

nannyml/stats/sum/calculator.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,29 @@ def _calculate(self, data: pd.DataFrame, *args, **kwargs) -> Result:
191191

192192
def _calculate_for_column(self, data: pd.DataFrame, column_name: str) -> Dict[str, Any]:
193193
result = {}
194-
value = _calculate_sum_value_stats(data[column_name])
195-
result['value'] = value
196-
result['sampling_error'] = self._sampling_error_components[column_name] * np.sqrt(data.shape[0])
197-
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
198-
result['lower_confidence_boundary'] = result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error']
199-
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
200-
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
201-
result['alert'] = _add_alert_flag(result)
202-
return result
194+
try:
195+
value = _calculate_sum_value_stats(data[column_name])
196+
result['value'] = value
197+
result['sampling_error'] = self._sampling_error_components[column_name] * np.sqrt(data.shape[0])
198+
result['upper_confidence_boundary'] = result['value'] + SAMPLING_ERROR_RANGE * result['sampling_error']
199+
result['lower_confidence_boundary'] = result['value'] - SAMPLING_ERROR_RANGE * result['sampling_error']
200+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
201+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
202+
result['alert'] = _add_alert_flag(result)
203+
except Exception as exc:
204+
if self._logger:
205+
self._logger.error(
206+
f"an unexpected exception occurred during calculation of column '{column_name}': " f"{exc}"
207+
)
208+
result['value'] = np.NaN
209+
result['sampling_error'] = np.NaN
210+
result['upper_confidence_boundary'] = np.NaN
211+
result['lower_confidence_boundary'] = np.NaN
212+
result['upper_threshold'] = self._upper_alert_thresholds[column_name]
213+
result['lower_threshold'] = self._lower_alert_thresholds[column_name]
214+
result['alert'] = np.NaN
215+
finally:
216+
return result
203217

204218

205219
def _create_multilevel_index(

0 commit comments

Comments
 (0)