Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`


Discussion:
Done inline during improve_partitions push.

Resolving patch:
diff --git a/great_expectations/rule_based_profiler/parameter_builder/metric_parameter_builder.py b/great_expectations/rule_based_profiler/parameter_builder/metric_parameter_builder.py
--- a/great_expectations/rule_based_profiler/parameter_builder/metric_parameter_builder.py
+++ b/great_expectations/rule_based_profiler/parameter_builder/metric_parameter_builder.py
@@ -1,3 +1,4 @@
+from numbers import Number
 from typing import Any, Dict, Optional, Union
 
 from great_expectations import DataContext
@@ -9,11 +10,6 @@
     ParameterContainer,
     build_parameter_container,
 )
-from great_expectations.rule_based_profiler.util import (
-    build_metric_domain_kwargs,
-    get_parameter_value_and_validate_return_type,
-)
-from great_expectations.validator.validation_graph import MetricConfiguration
 from great_expectations.validator.validator import Validator
 
 
@@ -29,6 +25,8 @@ def __init__(
         metric_name: str,
         metric_domain_kwargs: Optional[Union[str, dict]] = None,
         metric_value_kwargs: Optional[Union[str, dict]] = None,
+        enforce_numeric_metric: Optional[Union[str, bool]] = False,
+        replace_nan_with_zero: Optional[Union[str, bool]] = False,
         data_context: Optional[DataContext] = None,
         batch_request: Optional[Union[dict, str]] = None,
     ):
@@ -40,6 +38,8 @@ def __init__(
             metric_name: the name of a metric used in MetricConfiguration (must be a supported and registered metric)
             metric_domain_kwargs: used in MetricConfiguration
             metric_value_kwargs: used in MetricConfiguration
+            enforce_numeric_metric: used in MetricConfiguration to insure that metric computations return numeric values
+            replace_nan_with_zero: if set to True, then convert every NaN encountered to 0.0 (raise an exception otherwise)
             data_context: DataContext
             batch_request: specified in ParameterBuilder configuration to get Batch objects for parameter computation.
         """
@@ -53,6 +53,9 @@ def __init__(
         self._metric_domain_kwargs = metric_domain_kwargs
         self._metric_value_kwargs = metric_value_kwargs
 
+        self._enforce_numeric_metric = enforce_numeric_metric
+        self._replace_nan_with_zero = replace_nan_with_zero
+
     def _build_parameters(
         self,
         parameter_container: ParameterContainer,
@@ -74,41 +77,25 @@ def _build_parameters(
 
         batch_id: str = self.get_batch_id(variables=variables)
 
-        metric_domain_kwargs: dict = build_metric_domain_kwargs(
+        metric_computation_result: Dict[
+            str, Union[Any, Number, Dict[str, Any]]
+        ] = self.get_metric(
             batch_id=batch_id,
+            validator=validator,
+            metric_name=self._metric_name,
             metric_domain_kwargs=self._metric_domain_kwargs,
+            metric_value_kwargs=self._metric_value_kwargs,
+            enforce_numeric_metric=self._enforce_numeric_metric,
+            replace_nan_with_zero=self._replace_nan_with_zero,
             domain=domain,
             variables=variables,
             parameters=parameters,
         )
 
-        # Obtain value kwargs from rule state (i.e., variables and parameters); from instance variable otherwise.
-        metric_value_kwargs: Optional[
-            dict
-        ] = get_parameter_value_and_validate_return_type(
-            domain=domain,
-            parameter_reference=self._metric_value_kwargs,
-            expected_return_type=None,
-            variables=variables,
-            parameters=parameters,
-        )
-
-        metric_configuration_arguments: Dict[str, Any] = {
-            "metric_name": self._metric_name,
-            "metric_domain_kwargs": metric_domain_kwargs,
-            "metric_value_kwargs": metric_value_kwargs,
-            "metric_dependencies": None,
-        }
         parameter_values: Dict[str, Any] = {
-            f"$parameter.{self.parameter_name}": {
-                "value": validator.get_metric(
-                    metric=MetricConfiguration(**metric_configuration_arguments)
-                ),
-                "details": {
-                    "metric_configuration": metric_configuration_arguments,
-                },
-            },
+            f"$parameter.{self.parameter_name}": metric_computation_result,
         }
+
         build_parameter_container(
             parameter_container=parameter_container, parameter_values=parameter_values
         )
diff --git a/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py b/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py
--- a/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py
+++ b/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py
@@ -1,3 +1,4 @@
+from numbers import Number
 from typing import Any, Dict, List, Optional, Union
 
 import numpy as np
@@ -14,11 +15,9 @@
     build_parameter_container,
 )
 from great_expectations.rule_based_profiler.util import (
-    build_metric_domain_kwargs,
     get_parameter_value_and_validate_return_type,
 )
 from great_expectations.util import is_numeric
-from great_expectations.validator.validation_graph import MetricConfiguration
 from great_expectations.validator.validator import Validator
 
 NP_EPSILON: np.float64 = np.finfo(float).eps
@@ -48,6 +47,8 @@ def __init__(
         metric_name: str,
         metric_domain_kwargs: Optional[Union[str, dict]] = None,
         metric_value_kwargs: Optional[Union[str, dict]] = None,
+        enforce_numeric_metric: Optional[Union[str, bool]] = True,
+        replace_nan_with_zero: Optional[Union[str, bool]] = True,
         false_positive_rate: Optional[Union[float, str]] = 0.0,
         round_decimals: Optional[Union[int, str]] = False,
         truncate_distribution: Optional[
@@ -64,6 +65,8 @@ def __init__(
             metric_name: the name of a metric used in MetricConfiguration (must be a supported and registered metric)
             metric_domain_kwargs: used in MetricConfiguration
             metric_value_kwargs: used in MetricConfiguration
+            enforce_numeric_metric: used in MetricConfiguration to insure that metric computations return numeric values
+            replace_nan_with_zero: if set to True, then convert every NaN encountered to 0.0 (raise an exception otherwise)
             false_positive_rate: user-configured fraction between 0 and 1 -- "FP/(FP + TN)" -- where:
             FP stands for "false positives" and TN stands for "true negatives"; this rate specifies allowed "fall-out"
             (in addition, a helpful identity used in this method is: false_positive_rate = 1 - true_negative_rate).
@@ -85,6 +88,9 @@ def __init__(
         self._metric_domain_kwargs = metric_domain_kwargs
         self._metric_value_kwargs = metric_value_kwargs
 
+        self._enforce_numeric_metric = enforce_numeric_metric
+        self._replace_nan_with_zero = replace_nan_with_zero
+
         self._false_positive_rate = false_positive_rate
 
         self._round_decimals = round_decimals
@@ -159,50 +165,24 @@ def _build_parameters(
                 message=f"Utilizing a {self.__class__.__name__} requires a non-empty list of batch identifiers."
             )
 
-        metric_domain_kwargs: dict = build_metric_domain_kwargs(
-            batch_id=None,
+        metric_computation_result: Dict[
+            str, Union[Union[np.ndarray, List[Union[Any, Number]]], Dict[str, Any]]
+        ] = self.get_metrics(
+            batch_ids=batch_ids,
+            validator=validator,
+            metric_name=self._metric_name,
             metric_domain_kwargs=self._metric_domain_kwargs,
+            metric_value_kwargs=self._metric_value_kwargs,
+            enforce_numeric_metric=self._enforce_numeric_metric,
+            replace_nan_with_zero=self._replace_nan_with_zero,
             domain=domain,
             variables=variables,
             parameters=parameters,
         )
-
-        # Obtain value kwargs from rule state (i.e., variables and parameters); from instance variable otherwise.
-        metric_value_kwargs: Optional[
-            dict
-        ] = get_parameter_value_and_validate_return_type(
-            domain=domain,
-            parameter_reference=self._metric_value_kwargs,
-            expected_return_type=None,
-            variables=variables,
-            parameters=parameters,
-        )
-
         metric_values: Union[
-            np.ndarray,
-            List[Union[int, np.int32, np.int64, float, np.float32, np.float64]],
-        ] = []
-        metric_value: Union[int, np.int32, np.int64, float, np.float32, np.float64]
-        batch_id: str
-        for batch_id in batch_ids:
-            metric_domain_kwargs["batch_id"] = batch_id
-            metric_configuration_arguments: Dict[str, Any] = {
-                "metric_name": self._metric_name,
-                "metric_domain_kwargs": metric_domain_kwargs,
-                "metric_value_kwargs": metric_value_kwargs,
-                "metric_dependencies": None,
-            }
-            metric_value = validator.get_metric(
-                metric=MetricConfiguration(**metric_configuration_arguments)
-            )
-            if not is_numeric(value=metric_value):
-                raise ge_exceptions.ProfilerExecutionError(
-                    message=f"""Applicability of {self.__class__.__name__} is restricted to numeric-valued metrics \
-(value of type "{str(type(metric_value))}" was computed).
-"""
-                )
-
-            metric_values.append(metric_value)
+            np.ndarray, List[Union[Any, Number]]
+        ] = metric_computation_result["value"]
+        details: Dict[str, Any] = metric_computation_result["details"]
 
         # Obtain round_decimals directive from rule state (i.e., variables and parameters); from instance variable otherwise.
         round_decimals: Optional[
@@ -303,33 +283,13 @@ def _build_parameters(
         if upper_bound is not None:
             max_value = min(max_value, upper_bound)
 
-        # Obtain domain kwargs from rule state (i.e., variables and parameters); from instance variable otherwise.
-        domain_kwargs: dict = get_parameter_value_and_validate_return_type(
-            domain=domain,
-            parameter_reference="$domain.domain_kwargs",
-            expected_return_type=dict,
-            variables=variables,
-            parameters=parameters,
-        )
-
         parameter_values: Dict[str, Any] = {
             f"$parameter.{self.parameter_name}": {
                 "value": {
                     "min_value": min_value,
                     "max_value": max_value,
                 },
-                "details": {
-                    # Note: the "metric_domain_kwargs" value, used in "details", corresponds to the active Batch.
-                    # While any information can be placed into the "details" dictionary, this judicious choice will
-                    # allow for the relevant "details" to be used as "meta" in ExpectationConfiguration and render well,
-                    # without overwhelming the user (e.g., if instead all "batch_id" values were captured in "details").
-                    "metric_configuration": {
-                        "metric_name": self._metric_name,
-                        "metric_domain_kwargs": domain_kwargs,
-                        "metric_value_kwargs": metric_value_kwargs,
-                        "metric_dependencies": None,
-                    },
-                },
+                "details": details,
             },
         }
 
diff --git a/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py b/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py
--- a/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py
+++ b/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py
@@ -1,6 +1,10 @@
+import copy
 import uuid
 from abc import ABC, abstractmethod
-from typing import Dict, List, Optional, Union
+from numbers import Number
+from typing import Any, Dict, List, Optional, Union
+
+import numpy as np
 
 import great_expectations.exceptions as ge_exceptions
 from great_expectations.core.batch import Batch, BatchRequest
@@ -9,7 +13,13 @@
 from great_expectations.rule_based_profiler.parameter_builder.parameter_container import (
     ParameterContainer,
 )
-from great_expectations.rule_based_profiler.util import build_batch_request
+from great_expectations.rule_based_profiler.util import (
+    build_batch_request,
+    build_metric_domain_kwargs,
+    get_parameter_value_and_validate_return_type,
+)
+from great_expectations.util import is_numeric
+from great_expectations.validator.validation_graph import MetricConfiguration
 from great_expectations.validator.validator import Validator
 
 
@@ -148,6 +158,179 @@ def get_batch_id(
 
         return batch_ids[0]
 
+    def get_metric(
+        self,
+        batch_id: str,
+        validator: Validator,
+        metric_name: str,
+        metric_domain_kwargs: Optional[Union[str, dict]] = None,
+        metric_value_kwargs: Optional[Union[str, dict]] = None,
+        enforce_numeric_metric: Optional[Union[str, bool]] = False,
+        replace_nan_with_zero: Optional[Union[str, bool]] = False,
+        domain: Optional[Domain] = None,
+        variables: Optional[ParameterContainer] = None,
+        parameters: Optional[Dict[str, ParameterContainer]] = None,
+    ) -> Dict[str, Union[Any, Number, Dict[str, Any]]]:
+        metric_domain_kwargs = build_metric_domain_kwargs(
+            batch_id=batch_id,
+            metric_domain_kwargs=metric_domain_kwargs,
+            domain=domain,
+            variables=variables,
+            parameters=parameters,
+        )
+        # Obtain value kwargs from rule state (i.e., variables and parameters); from instance variable otherwise.
+        metric_value_kwargs = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=metric_value_kwargs,
+            expected_return_type=None,
+            variables=variables,
+            parameters=parameters,
+        )
+
+        # Obtain enforce_numeric_metric from rule state (i.e., variables and parameters); from instance variable otherwise.
+        enforce_numeric_metric = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=enforce_numeric_metric,
+            expected_return_type=bool,
+            variables=variables,
+            parameters=parameters,
+        )
+
+        # Obtain replace_nan_with_zero from rule state (i.e., variables and parameters); from instance variable otherwise.
+        replace_nan_with_zero = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=replace_nan_with_zero,
+            expected_return_type=bool,
+            variables=variables,
+            parameters=parameters,
+        )
+
+        metric_configuration_arguments: Dict[str, Any] = {
+            "metric_name": metric_name,
+            "metric_domain_kwargs": metric_domain_kwargs,
+            "metric_value_kwargs": metric_value_kwargs,
+            "metric_dependencies": None,
+        }
+        metric_value: Union[Any, Number] = validator.get_metric(
+            metric=MetricConfiguration(**metric_configuration_arguments)
+        )
+        if enforce_numeric_metric:
+            if not is_numeric(value=metric_value):
+                raise ge_exceptions.ProfilerExecutionError(
+                    message=f"""Applicability of {self.__class__.__name__} is restricted to numeric-valued metrics \
+(value of type "{str(type(metric_value))}" was computed).
+"""
+                )
+            if np.isnan(metric_value):
+                if not replace_nan_with_zero:
+                    raise ValueError(
+                        f"""Computation of metric "{metric_name}" resulted in NaN ("not a number") value.
+"""
+                    )
+                metric_value = 0.0
+
+        return {
+            "value": metric_value,
+            "details": {
+                "metric_configuration": metric_configuration_arguments,
+            },
+        }
+
+    def get_metrics(
+        self,
+        batch_ids: List[str],
+        validator: Validator,
+        metric_name: str,
+        metric_domain_kwargs: Optional[Union[str, dict]] = None,
+        metric_value_kwargs: Optional[Union[str, dict]] = None,
+        enforce_numeric_metric: Optional[Union[str, bool]] = False,
+        replace_nan_with_zero: Optional[Union[str, bool]] = False,
+        domain: Optional[Domain] = None,
+        variables: Optional[ParameterContainer] = None,
+        parameters: Optional[Dict[str, ParameterContainer]] = None,
+    ) -> Dict[str, Union[Union[np.ndarray, List[Union[Any, Number]]], Dict[str, Any]]]:
+        domain_kwargs = build_metric_domain_kwargs(
+            batch_id=None,
+            metric_domain_kwargs=metric_domain_kwargs,
+            domain=domain,
+            variables=variables,
+            parameters=parameters,
+        )
+
+        metric_domain_kwargs: dict = copy.deepcopy(domain_kwargs)
+
+        # Obtain value kwargs from rule state (i.e., variables and parameters); from instance variable otherwise.
+        metric_value_kwargs = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=metric_value_kwargs,
+            expected_return_type=None,
+            variables=variables,
+            parameters=parameters,
+        )
+
+        # Obtain enforce_numeric_metric from rule state (i.e., variables and parameters); from instance variable otherwise.
+        enforce_numeric_metric = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=enforce_numeric_metric,
+            expected_return_type=bool,
+            variables=variables,
+            parameters=parameters,
+        )
+
+        # Obtain replace_nan_with_zero from rule state (i.e., variables and parameters); from instance variable otherwise.
+        replace_nan_with_zero = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=replace_nan_with_zero,
+            expected_return_type=bool,
+            variables=variables,
+            parameters=parameters,
+        )
+
+        metric_values: List[Union[Any, Number]] = []
+
+        metric_value: Union[Any, Number]
+        batch_id: str
+        for batch_id in batch_ids:
+            metric_domain_kwargs["batch_id"] = batch_id
+            metric_configuration_arguments: Dict[str, Any] = {
+                "metric_name": metric_name,
+                "metric_domain_kwargs": metric_domain_kwargs,
+                "metric_value_kwargs": metric_value_kwargs,
+                "metric_dependencies": None,
+            }
+            metric_value = validator.get_metric(
+                metric=MetricConfiguration(**metric_configuration_arguments)
+            )
+            if enforce_numeric_metric:
+                if not is_numeric(value=metric_value):
+                    raise ge_exceptions.ProfilerExecutionError(
+                        message=f"""Applicability of {self.__class__.__name__} is restricted to numeric-valued metrics \
+(value of type "{str(type(metric_value))}" was computed).
+"""
+                    )
+                if np.isnan(metric_value):
+                    if not replace_nan_with_zero:
+                        raise ValueError(
+                            f"""Computation of metric "{metric_name}" resulted in NaN ("not a number") value.
+"""
+                        )
+                    metric_value = 0.0
+
+            metric_values.append(metric_value)
+
+        return {
+            "value": metric_values,
+            "details": {
+                "metric_configuration": {
+                    "metric_name": metric_name,
+                    "domain_kwargs": domain_kwargs,
+                    "metric_value_kwargs": metric_value_kwargs,
+                    "metric_dependencies": None,
+                },
+                "num_batches": len(batch_ids),
+            },
+        }
+
     @property
     def parameter_name(self) -> str:
         return self._parameter_name


Test patch:
diff --git a/tests/rule_based_profiler/bobby_user_workflow_fixture.py b/tests/rule_based_profiler/bobby_user_workflow_fixture.py
--- a/tests/rule_based_profiler/bobby_user_workflow_fixture.py
+++ b/tests/rule_based_profiler/bobby_user_workflow_fixture.py
@@ -30,9 +30,10 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "table.row_count",
-                            "metric_domain_kwargs": {},
-                        }
-                    }
+                            "domain_kwargs": {},
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -49,11 +50,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "VendorID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -70,11 +72,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "VendorID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -91,11 +94,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "passenger_count",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -112,11 +116,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "passenger_count",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -133,11 +138,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "trip_distance",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -154,11 +160,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "trip_distance",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -175,11 +182,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "RatecodeID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -196,11 +204,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "RatecodeID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -217,11 +226,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "PULocationID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -238,11 +248,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "PULocationID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -259,11 +270,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "DOLocationID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -280,11 +292,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "DOLocationID",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -301,11 +314,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "payment_type",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -322,11 +336,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "payment_type",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -343,11 +358,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "fare_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -364,11 +380,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "fare_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -385,11 +402,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "extra",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -406,11 +424,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "extra",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -427,11 +446,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "mta_tax",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -448,11 +468,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "mta_tax",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -469,11 +490,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "tip_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -490,11 +512,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "tip_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -511,11 +534,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "tolls_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -532,11 +556,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "tolls_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -553,11 +578,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "improvement_surcharge",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -574,11 +600,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "improvement_surcharge",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -595,11 +622,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "total_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -616,11 +644,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "total_amount",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -637,11 +666,12 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "congestion_surcharge",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
             },
         ),
@@ -658,13 +688,14 @@ def bobby_columnar_table_multi_batch():
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "metric_domain_kwargs": {
+                            "domain_kwargs": {
                                 "column": "congestion_surcharge",
                             },
-                        }
-                    }
+                        },
+                        "num_batches": 2,
+                    },
                 },
-            }
+            },
         ),
     ]