Repository: alteryx/woodwork
Pull request #1524 (2022-09-15 22:09:04)

Add ignore_zeros parameter to box_plot_dict

codecov[bot]: # [Codecov](https://codecov.io/gh/alteryx/woodwork/pull/1524?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx) Report
> Merging [#1524](https://codecov.io/gh/alteryx/woodwork/pull/1524?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx) (216f6f7) into [main](https://codecov.io/gh/alteryx/woodwork/commit/c7704e19df12ca840df5fe8210d0e53988608c10?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx) (c7704e1) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

> :exclamation: Current head 216f6f7 differs from pull request most recent head d3afc2e. Consider uploading reports for the commit d3afc2e to get more accurate results

```diff
@@           Coverage Diff           @@
##             main    #1524   +/-   ##
=======================================
  Coverage   98.71%   98.71%           
=======================================
  Files          95       95           
  Lines       10969    10996   +27     
=======================================
+ Hits        10828    10855   +27     
  Misses        141      141           
```


| [Impacted Files](https://codecov.io/gh/alteryx/woodwork/pull/1524?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx) | Coverage Δ | |
|---|---|---|
| [woodwork/column\_accessor.py](https://codecov.io/gh/alteryx/woodwork/pull/1524/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx#diff-d29vZHdvcmsvY29sdW1uX2FjY2Vzc29yLnB5) | `100.00% <100.00%> (ø)` | |
| [.../statistics\_utils/\_get\_box\_plot\_info\_for\_column.py](https://codecov.io/gh/alteryx/woodwork/pull/1524/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx#diff-d29vZHdvcmsvc3RhdGlzdGljc191dGlscy9fZ2V0X2JveF9wbG90X2luZm9fZm9yX2NvbHVtbi5weQ==) | `100.00% <100.00%> (ø)` | |
| [woodwork/tests/accessor/test\_statistics.py](https://codecov.io/gh/alteryx/woodwork/pull/1524/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx#diff-d29vZHdvcmsvdGVzdHMvYWNjZXNzb3IvdGVzdF9zdGF0aXN0aWNzLnB5) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=alteryx)


Patch:
diff --git a/docs/source/release_notes.rst b/docs/source/release_notes.rst
index e93d2a1..ab03b43 100644
--- a/docs/source/release_notes.rst
+++ b/docs/source/release_notes.rst
@@ -6,6 +6,7 @@ Release Notes
 Future Release
 ==============
     * Enhancements
+        * Added ``ignore_zeros`` as an argument for ``box_plot_dict`` to allow for calculations of outliers without 0 values (:pr:`1524`)
     * Fixes
         * Fix datetime pivot point to be set at current year + 10 rather than the default for two-digit years when ``datetime_format`` provided (:pr:`1512`)
     * Changes
diff --git a/woodwork/column_accessor.py b/woodwork/column_accessor.py
index a627477..5e0b187 100644
--- a/woodwork/column_accessor.py
+++ b/woodwork/column_accessor.py
@@ -389,7 +389,12 @@ class WoodworkColumnAccessor:
         self._schema._set_semantic_tags(semantic_tags)
 
     @_check_column_schema
-    def box_plot_dict(self, quantiles=None, include_indices_and_values=True):
+    def box_plot_dict(
+        self,
+        quantiles=None,
+        include_indices_and_values=True,
+        ignore_zeros=False,
+    ):
         """Gets the information necessary to create a box and whisker plot with outliers for a numeric column
         using the IQR method.
 
@@ -400,6 +405,8 @@ class WoodworkColumnAccessor:
             include_indices_and_values (bool, optional): Whether or not the lists containing individual
                 outlier values and their indices will be included in the returned dictionary.
                 Defaults to True.
+            ignore_zeros (bool): Whether to ignore 0 values (not NaN values) when calculating the box plot and outliers.
+                Defaults to False.
 
         Note:
             The minimum quantiles necessary for building a box plot using the IQR method are the
@@ -429,6 +436,7 @@ class WoodworkColumnAccessor:
             self._series,
             quantiles=quantiles,
             include_indices_and_values=include_indices_and_values,
+            ignore_zeros=ignore_zeros,
         )
 
     @_check_column_schema
diff --git a/woodwork/statistics_utils/_get_box_plot_info_for_column.py b/woodwork/statistics_utils/_get_box_plot_info_for_column.py
index 7495b6f..374a826 100644
--- a/woodwork/statistics_utils/_get_box_plot_info_for_column.py
+++ b/woodwork/statistics_utils/_get_box_plot_info_for_column.py
@@ -11,6 +11,7 @@ def _get_box_plot_info_for_column(
     series,
     quantiles=None,
     include_indices_and_values=True,
+    ignore_zeros=False,
 ):
     """Gets the information necessary to create a box and whisker plot with outliers for a numeric column
         using the IQR method.
@@ -23,6 +24,8 @@ def _get_box_plot_info_for_column(
         include_indices_and_values (bool, optional): Whether or not the lists containing individual
             outlier values and their indices will be included in the returned dictionary.
             Defaults to True.
+        ignore_zeros (bool): Whether to ignore 0 values (not NaN values) when calculating the box plot and outliers.
+                Defaults to False.
 
     Note:
         The minimum quantiles necessary for building a box plot using the IQR method are the
@@ -62,6 +65,9 @@ def _get_box_plot_info_for_column(
     # remove null values from the data
     series = series.dropna()
 
+    if ignore_zeros:
+        series = series[series.astype(bool)]
+
     outliers_dict = {}
     # An empty or fully null Series has no outliers, bounds, or quantiles
     if series.shape[0] == 0:


Test patch:
diff --git a/woodwork/tests/accessor/test_statistics.py b/woodwork/tests/accessor/test_statistics.py
index 0ce9544..eef28b5 100644
--- a/woodwork/tests/accessor/test_statistics.py
+++ b/woodwork/tests/accessor/test_statistics.py
@@ -1976,3 +1976,38 @@ def test_parse_measures_bad_string():
     msg = "Unrecognized dependence measure ruler"
     with pytest.raises(ValueError, match=msg):
         _parse_measures(["mutual_info", "ruler"])
+
+
+def test_box_plot_ignore_zeros():
+    zeros_df = pd.Series(list(range(1, 100)) + [0] * 100)
+    no_zeros_df = pd.Series(range(1, 100))
+    zeros_df.ww.init()
+    no_zeros_df.ww.init()
+
+    zeros_box_ignored = zeros_df.ww.box_plot_dict(ignore_zeros=True)
+    zeros_box_not_ignored = zeros_df.ww.box_plot_dict()
+
+    no_zeros_box_ignored = no_zeros_df.ww.box_plot_dict(ignore_zeros=True)
+    no_zeros_box_not_ignored = no_zeros_df.ww.box_plot_dict()
+
+    assert zeros_box_ignored == no_zeros_box_ignored
+    assert zeros_box_ignored == no_zeros_box_not_ignored
+    assert zeros_box_not_ignored != no_zeros_box_ignored
+
+
+@pytest.mark.parametrize("dtype", ["IntegerNullable", "Double"])
+def test_box_plot_ignore_zeros_null(dtype):
+    zeros_df = pd.Series(list(range(1, 100)) + [0] * 100 + [None])
+    no_zeros_df = pd.Series(list(range(1, 100)) + [None])
+    zeros_df.ww.init(logical_type=dtype)
+    no_zeros_df.ww.init(logical_type=dtype)
+
+    zeros_box_ignored = zeros_df.ww.box_plot_dict(ignore_zeros=True)
+    zeros_box_not_ignored = zeros_df.ww.box_plot_dict()
+
+    no_zeros_box_ignored = no_zeros_df.ww.box_plot_dict(ignore_zeros=True)
+    no_zeros_box_not_ignored = no_zeros_df.ww.box_plot_dict()
+
+    assert zeros_box_ignored == no_zeros_box_ignored
+    assert zeros_box_ignored == no_zeros_box_not_ignored
+    assert zeros_box_not_ignored != no_zeros_box_ignored