From 67cf16923af1d93aba15e873caa8f080f56ed5b8 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 31 Mar 2022 09:06:49 +0100 Subject: [PATCH 1/3] allclose --- cf/data/data.py | 59 ++++++++++++++------------------------------ cf/test/test_Data.py | 24 ++++++++++++++++++ 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/cf/data/data.py b/cf/data/data.py index c93d48f7d4..459b50dca6 100644 --- a/cf/data/data.py +++ b/cf/data/data.py @@ -4272,25 +4272,6 @@ def _binary_operation(self, other, method): return self - def __query_set__(self, values): - """Implements the “member of set” condition.""" - i = iter(values) - v = next(i) - - out = self == v - for v in i: - out |= self == v - - return out - - def __query_wi__(self, value): - """Implements the “within a range” condition.""" - return (self >= value[0]) & (self <= value[1]) - - def __query_wo__(self, value): - """TODO.""" - return (self < value[0]) | (self > value[1]) - @classmethod def concatenate(cls, data, axis=0, _preserve=True): """Join a sequence of data arrays together. @@ -7211,55 +7192,51 @@ def all(self): return True + @daskified(_DASKIFIED_VERBOSE) def allclose(self, y, rtol=None, atol=None): - """Returns True if two broadcastable arrays have equal values, - False otherwise. + """Whether an array is element-wise equal within a tolerance. + + Return True if the data is broadcastable to array *y* and + element-wise equal within a tolerance. - Two real numbers ``x`` and ``y`` are considered equal if - ``|x-y|<=atol+rtol|y|``, where ``atol`` (the tolerance on absolute - differences) and ``rtol`` (the tolerance on relative differences) - are positive, typically very small numbers. See the *atol* and - *rtol* parameters. + {{equals tolerance}} .. seealso:: `all`, `any`, `isclose` :Parameters: y: data_like + The data to compare. - atol: `float`, optional - The absolute tolerance for all numerical comparisons. By - default the value returned by the `atol` function is used. + {{rtol: number, optional}} - rtol: `float`, optional - The relative tolerance for all numerical comparisons. By - default the value returned by the `rtol` function is used. + {{atol: number, optional}} :Returns: - `bool` + `Data` + A scalar boolean array that is `True if the two arrays + are equal within the given tolerance, or `False` + otherwise. - **Examples:** + **Examples** >>> d = cf.Data([1000, 2500], 'metre') >>> e = cf.Data([1, 2.5], 'km') - >>> d.allclose(e) + >>> bool(d.allclose(e)) True >>> d = cf.Data(['ab', 'cdef']) - >>> d.allclose([[['ab', 'cdef']]]) - True - - >>> d.allclose(e) + >>> bool(d.allclose([[['ab', 'cdef']]])) True >>> d = cf.Data([[1000, 2500], [1000, 2500]], 'metre') >>> e = cf.Data([1, 2.5], 'km') - >>> d.allclose(e) + >>> bool(d.allclose(e)) True >>> d = cf.Data([1, 1, 1], 's') - >>> d.allclose(1) + >>> bool(d.allclose(1)) True """ diff --git a/cf/test/test_Data.py b/cf/test/test_Data.py index 7e991b8f68..5b3b9f96c4 100644 --- a/cf/test/test_Data.py +++ b/cf/test/test_Data.py @@ -3927,6 +3927,30 @@ def test_Data_set_units(self): with self.assertRaises(ValueError): d.set_units("km") + def test_Data_allclose(self): + d = cf.Data([1000, 2500], "metre") + e = cf.Data([1, 2.5], "km") + self.assertTrue(d.allclose(e)) + + d = cf.Data([[1000, 2500], [1000, 2500]], "metre") + self.assertTrue(d.allclose(e)) + + d = cf.Data(["ab", "cdef"]) + e = [[["ab", "cdef"]]] + self.assertTrue(d.allclose(e)) + + d = cf.Data([1, 1, 1], "s") + e = 1 + self.assertTrue(d.allclose(e)) + + # Incompatible units + e = cf.Data([1, 1, 1], "m") + self.assertFalse(d.allclose(e)) + + # Not broadcastable + with self.assertRaises(ValueError): + d.allclose([1, 2]) + if __name__ == "__main__": print("Run date:", datetime.datetime.now()) From dca2a6ff25638653687424b3d5250fdb9df69f30 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 31 Mar 2022 09:10:05 +0100 Subject: [PATCH 2/3] allclose --- cf/test/test_Data.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cf/test/test_Data.py b/cf/test/test_Data.py index 5b3b9f96c4..1b93effa03 100644 --- a/cf/test/test_Data.py +++ b/cf/test/test_Data.py @@ -3944,8 +3944,8 @@ def test_Data_allclose(self): self.assertTrue(d.allclose(e)) # Incompatible units - e = cf.Data([1, 1, 1], "m") - self.assertFalse(d.allclose(e)) + with self.assertRaises(ValueError): + d.allclose(cf.Data([1, 1, 1], "m")) # Not broadcastable with self.assertRaises(ValueError): From 36baa69ea6eff4567072ec101efd13c645e663a8 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 22 Jun 2022 12:07:34 +0100 Subject: [PATCH 3/3] Typo Co-authored-by: Sadie L. Bartholomew --- cf/data/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf/data/data.py b/cf/data/data.py index f2bdb9eaa7..3c6a4bb60d 100644 --- a/cf/data/data.py +++ b/cf/data/data.py @@ -5360,7 +5360,7 @@ def allclose(self, y, rtol=None, atol=None): :Returns: `Data` - A scalar boolean array that is `True if the two arrays + A scalar boolean array that is `True` if the two arrays are equal within the given tolerance, or `False` otherwise.