Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions cf/data/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8361,24 +8361,25 @@ def binary_mask(self):
m.override_units(_units_1, inplace=True)
return m

@daskified(_DASKIFIED_VERBOSE)
@_deprecated_kwarg_check("i")
@_inplace_enabled(default=False)
def clip(self, a_min, a_max, units=None, inplace=False, i=False):
"""Clip (limit) the values in the data array in place.

Given an interval, values outside the interval are clipped to the
interval edges. For example, if an interval of [0, 1] is specified
then values smaller than 0 become 0 and values larger than 1
become 1.
Given an interval, values outside the interval are clipped to
the interval edges. For example, if an interval of [0, 1] is
specified then values smaller than 0 become 0 and values
larger than 1 become 1.

:Parameters:

a_min:
a_min: number
Minimum value. If `None`, clipping is not performed on
lower interval edge. Not more than one of `a_min` and
`a_max` may be `None`.

a_max:
a_max: number
Maximum value. If `None`, clipping is not performed on
upper interval edge. Not more than one of `a_min` and
`a_max` may be `None`.
Expand All @@ -8398,31 +8399,35 @@ def clip(self, a_min, a_max, units=None, inplace=False, i=False):
`None` is returned.


**Examples:**
**Examples**

>>> g = f.clip(-90, 90)
>>> g = f.clip(-90, 90, 'degrees_north')
>>> d = cf.Data(np.arange(12).reshape(3, 4), 'm')
>>> print(d.array)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
>>> print(d.clip(2, 10).array)
[[ 2 2 2 3]
[ 4 5 6 7]
[ 8 9 10 10]]
>>> print(d.clip(0.003, 0.009, 'km').array)
[[3. 3. 3. 3.]
[4. 5. 6. 7.]
[8. 9. 9. 9.]]

"""
d = _inplace_enabled_define_and_cleanup(self)

if units is not None:
# Convert the limits to the same units as the data array
units = Units(units)
self_units = d.Units
self_units = self.Units
if self_units != units:
a_min = Units.conform(a_min, units, self_units)
a_max = Units.conform(a_max, units, self_units)
# --- End: if

config = d.partition_configuration(readonly=False)

for partition in d.partitions.matrix.flat:
partition.open(config)
array = partition.array
array.clip(a_min, a_max, out=array)
partition.close()
a_min = Units.conform(np.asanyarray(a_min), units, self_units)
a_max = Units.conform(np.asanyarray(a_max), units, self_units)

d = _inplace_enabled_define_and_cleanup(self)
dx = self._get_dask()
dx = da.clip(dx, a_min, a_max)
d._set_dask(dx, reset_mask_hardness=False)
return d

@classmethod
Expand Down
3 changes: 1 addition & 2 deletions cf/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from collections.abc import Iterable
from itertools import product
from marshal import dumps
from math import ceil as math_ceil
from numbers import Integral
from os import getpid, listdir, mkdir
from os.path import abspath as _os_path_abspath
Expand All @@ -25,9 +24,9 @@

import cfdm
import netCDF4
import numpy as np
from dask import config
from dask.utils import parse_bytes
import numpy as np
from numpy import __file__ as _numpy__file__
from numpy import __version__ as _numpy__version__
from numpy import all as _numpy_all
Expand Down
29 changes: 9 additions & 20 deletions cf/test/test_Data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1506,30 +1506,19 @@ def test_Data_binary_mask(self):
m = d.binary_mask
self.assertTrue((d.binary_mask.array == [[0, 1, 0, 0]]).all())

@unittest.skipIf(TEST_DASKIFIED_ONLY, "no attr. 'partition_configuration'")
def test_Data_clip(self):
if self.test_only and inspect.stack()[0][3] not in self.test_only:
return

c0 = -53.234
c1 = 34.345456567

a = self.a + 0.34567
ac = np.clip(a, c0, c1)
a = np.arange(12).reshape(3, 4)
d = cf.Data(a, "m", chunks=2)

d = cf.Data(a, "km")
self.assertIsNotNone(d.clip(c0, c1))
self.assertIsNone(d.clip(c0, c1, inplace=True))

d = cf.Data(a, "km")
e = d.clip(c0, c1)
self.assertTrue((e.array == ac).all())
self.assertIsNone(d.clip(-1, 12, inplace=True))

e = d.clip(c0 * 1000, c1 * 1000, units="m")
self.assertTrue((e.array == ac).all())
b = np.clip(a, 2, 10)
e = d.clip(2, 10)
self.assertTrue((e.array == b).all())

d.clip(c0 * 100, c1 * 100, units="10m", inplace=True)
self.assertTrue(d.allclose(ac, rtol=1e-05, atol=1e-08))
b = np.clip(a, 3, 9)
e = d.clip(0.003, 0.009, "km")
self.assertTrue((e.array == b).all())

@unittest.skipIf(TEST_DASKIFIED_ONLY, "no attr. 'partition_configuration'")
def test_Data_months_years(self):
Expand Down