Skip to content

Commit

Permalink
Merge 85edbe2 into b0c4a05
Browse files Browse the repository at this point in the history
  • Loading branch information
scanny committed Nov 6, 2020
2 parents b0c4a05 + 85edbe2 commit 1e909b5
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 282 deletions.
23 changes: 12 additions & 11 deletions src/cr/cube/cubepart.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,18 @@ def dimension_types(self):
return tuple(d.dimension_type for d in self._dimensions)

def evaluate(self, measure_expr):
"""Return 1D/2D ndarray, values evaluated given the function specification
The `function_spec` contains the function to apply and its parameters, e.g.:
```
{
"function": "one_sided_moving_avg",
"kwargs": {"base_measure": "means", "window": 3},
}
```
This `function_spec` object would apply the function `one_sided_moving_avg` to
the `base_measure` means, using 3 as window.
"""Return 1D/2D ndarray result of evaluating `measure_expr`.
`measure_expr` contains the function to apply and its parameters, like::
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 3
}
This expression specifies application of the `one_sided_moving_avg` function to
the `col_percent` base-measure, with a sliding window of 3 periods.
"""
function = measure_expr.get("function", None)
if function != "one_sided_moving_avg":
Expand Down
11 changes: 5 additions & 6 deletions src/cr/cube/noa/smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def _base_measure(self):

@lazyproperty
def _base_values(self):
""" ndarray, base measure values of the current partition
"""ndarray base-measure values from the partition.
The `base_measure` is expressed in the kwargs of the function_spec and used
to get the values for the partition.
Expand All @@ -96,18 +96,17 @@ def _can_smooth(self):
# --- and it must be at least 2.
if self._window > self._base_values.shape[-1] or self._window < 2:
warnings.warn(
"No smoothing performed. Window (value: {}) parameter is not "
"valid: window must be less than equal to the total period "
"(value: {}) and positive".format(
self._window, self._base_values.shape[-1]
"No smoothing performed. Smoothing window must be between 2 and the "
"number of periods ({}), got {}".format(
self._base_values.shape[-1], self._window
),
UserWarning,
)
return False
# --- no smoothing when column dimension is not a categorical date ---
if not self._is_cat_date:
warnings.warn(
"No smoothing performed. Column dimension must be a categorical date"
"No smoothing performed. Column dimension must be a categorical date."
)
return False
return True
Expand Down
24 changes: 0 additions & 24 deletions tests/expectations/cat-date-x-cat-unsmoothed-col-pct.py

This file was deleted.

7 changes: 0 additions & 7 deletions tests/expectations/cat-x-cat-date-smoothed-col-idx-w1.py

This file was deleted.

1 change: 0 additions & 1 deletion tests/expectations/cat-x-cat-unsmoothed-col-pct.py

This file was deleted.

1 change: 0 additions & 1 deletion tests/expectations/cat-x-mr-unsmoothed-col-pct.py

This file was deleted.

123 changes: 0 additions & 123 deletions tests/expectations/mr-x-ca-cat-x-ca-subvar-unsmoothed-col-pct.py

This file was deleted.

6 changes: 0 additions & 6 deletions tests/expectations/mr-x-mr-unsmoothed-col-pct.py

This file was deleted.

6 changes: 5 additions & 1 deletion tests/integration/test_pairwise_significance.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,11 @@ def test_cat_x_cat_wgtd_pairwise_t_tests(self):
actual.p_vals, load_python_expression("cat-x-cat-wgtd-pw-pvals")
)
np.testing.assert_array_equal(
pairwise_indices, load_python_expression("cat-x-cat-wgtd-pw-indices")
pairwise_indices,
np.array(
load_python_expression("cat-x-cat-wgtd-pw-indices"),
dtype=tuple,
),
)

def test_cat_x_cat_wgtd_scale_means_pariwise_t_tests(self):
Expand Down
97 changes: 63 additions & 34 deletions tests/integration/test_smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@


class DescribeSliceSmoothing(object):
"""Integration-test suite for _Slice.evaluate() method."""

@pytest.mark.parametrize(
"fixture, window, expectation",
(
(CR.CAT_X_CAT_DATE, 1, "cat-x-cat-date-smoothed-col-idx-w1"),
(CR.CAT_X_CAT_DATE_WGTD, 4, "cat-x-cat-date-wgtd-smoothed-col-idx-w4"),
(CR.CAT_X_MR_X_CAT_DATE, 3, "cat-x-mr-x-cat-date-smoothed-col-idx-w3"),
(
Expand Down Expand Up @@ -48,7 +49,6 @@ def it_provides_smoothed_col_index_for_compatible_cubes(
@pytest.mark.parametrize(
"fixture, window, expectation",
(
(CR.CAT_X_CAT_DATE, 1, "cat-x-cat-date-smoothed-col-pct-w1"),
(CR.CAT_X_CAT_DATE_WGTD, 4, "cat-x-cat-date-wgtd-smoothed-col-pct-w4"),
(CR.CAT_X_MR_X_CAT_DATE, 3, "cat-x-mr-x-cat-date-smoothed-col-pct-w3"),
(
Expand Down Expand Up @@ -107,45 +107,65 @@ def it_provides_smoothed_scale_means_for_compatible_cubes(
)

@pytest.mark.parametrize(
"fixture, expectation",
"fixture",
(
(CR.CAT_X_MR, "cat-x-mr-unsmoothed-col-pct"),
(CR.MR_X_MR, "mr-x-mr-unsmoothed-col-pct"),
(CR.MR_X_CA_CAT_X_CA_SUBVAR, "mr-x-ca-cat-x-ca-subvar-unsmoothed-col-pct"),
(CR.CAT_X_CAT, "cat-x-cat-unsmoothed-col-pct"),
(CR.CAT_DATE_X_CAT, "cat-date-x-cat-unsmoothed-col-pct"),
CR.CAT_X_MR,
CR.MR_X_MR,
CR.MR_X_CA_CAT_X_CA_SUBVAR,
CR.CAT_DATE_X_CAT,
),
)
def it_does_not_smooth_col_pct_for_incompatible_cubes(self, fixture, expectation):
cube = Cube(fixture)
slice_ = cube.partitions[0]
col_percent = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 3,
}
)
np.testing.assert_array_almost_equal(
col_percent, load_python_expression(expectation)
def it_warns_and_does_not_smooth_when_dimension_is_not_smoothable(self, fixture):
slice_ = Cube(fixture).partitions[0]
base_values = slice_.column_percentages
expected_warning_regex = (
r"No smoothing performed. Column dimension must be a categorical date."
)

def it_doesnt_smooth_counts_when_window_is_not_valid(self):
slice_ = Cube(CR.CAT_X_CAT_DATE).partitions[0]
col_percent = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 1,
}
with pytest.warns(UserWarning, match=expected_warning_regex):
smoothed_values = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 3,
}
)

np.testing.assert_array_almost_equal(smoothed_values, base_values)

@pytest.mark.parametrize(
"fixture, base_measure, prop_name, periods, window",
(
(CR.CAT_X_CAT_DATE, "col_percent", "column_percentages", 4, 1),
(CR.CAT_X_CAT_DATE, "col_index", "column_index", 4, 1),
(CR.CAT_X_CAT, "col_percent", "column_percentages", 2, 3),
),
)
def it_warns_and_does_not_smooth_when_window_is_invalid(
self, fixture, base_measure, prop_name, periods, window
):
slice_ = Cube(fixture).partitions[0]
base_values = getattr(slice_, prop_name)
expected_warning_regex = (
r"No smoothing performed. Smoothing window must be between 2 and the "
r"number of periods \(%d\), got %d" % (periods, window)
)
slice2_ = Cube(CR.CAT_X_CAT_DATE).partitions[0]
col_percent2 = slice2_.column_percentages

np.testing.assert_array_almost_equal(col_percent, col_percent2)
with pytest.warns(UserWarning, match=expected_warning_regex):
smoothed_values = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": base_measure,
"window": window,
}
)

np.testing.assert_array_almost_equal(smoothed_values, base_values)


class DescribeStrandMeansSmoothing(object):
"""Integration-test suite for _Strand.evaluate() method."""

def it_provides_smoothed_means_cat_date(self):
strand_ = Cube(CR.CAT_DATE_MEAN).partitions[0]
means = strand_.evaluate(
Expand All @@ -155,11 +175,20 @@ def it_provides_smoothed_means_cat_date(self):
means, [np.nan, np.nan, 2.65670765025029, 2.5774816240050358]
)

def it_doesnt_smoot_means_mr_mean_filt_wgtd(self):
def it_does_not_smooth_means_mr_mean_filt_wgtd(self):
strand_ = Cube(CR.MR_MEAN_FILT_WGTD).partitions[0]
means = strand_.evaluate(
{"function": "one_sided_moving_avg", "base_measure": "mean", "window": 3}
expected_warning_regex = (
r"No smoothing performed. Column dimension must be a categorical date."
)

with pytest.warns(UserWarning, match=expected_warning_regex):
means = strand_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "mean",
"window": 3,
}
)
np.testing.assert_array_almost_equal(
means, [3.724051, 2.578429, 2.218593, 1.865335]
)

0 comments on commit 1e909b5

Please sign in to comment.