cf.Field.where

Field.where(condition, x=None, y=None, inplace=False, construct=None, i=False, _debug=False, item=None, **item_options)[source]

Assign to data elements depending on a condition.

Data can be changed by assigning to elements that are selected by a condition based on the data values of the field construct or on its metadata constructs.

Different values can be assigned to where the conditions are, and are not, met.

Missing data

Data array elements may be set to missing values by assigning them to the cf.masked constant, or by assignment missing data elements of array-valued x and y parameters.

By default the data mask is “hard”, meaning that masked values can not be changed by assigning them to another value. This behaviour may be changed by setting the hardmask attribute of the field construct to False, thereby making the data mask “soft” and allowing masked elements to be set to non-masked values.

Parameters:
condition:

The condition which determines how to assign values to the data.

In general it may be any scalar or array-like object (such as a numpy, Data or Field object) that is broadcastable to the shape of the data. Assignment from the x and y parameters will be done where elements of the condition evaluate to True and False respectively.

Parameter example:

f.where(f.data<0, x=-999) will set all data values that are less than zero to -999.

Parameter example:

f.where(True, x=-999) will set all data values to -999. This is equivalent to f[...] = -999.

Parameter example:

f.where(False, y=-999) will set all data values to -999. This is equivalent to f[...] = -999.

Parameter example:

If field construct f has shape (5, 3) then f.where([True, False, True], x=-999, y=cf.masked) will set data values in columns 0 and 2 to -999, and data values in column 1 to missing data. This works because the condition has shape (3,) which broadcasts to the field construct’s shape.

If condition is a Query object then this implies a condition defined by applying the query to the field construct’s data (or a metadata construct’s data if the construct parameter is set).

Parameter example:

f.where(cf.lt(0), x=-999) will set all data values that are less than zero to -999. This is equivalent to f.where(f.data<0, x=-999).

If condition is another field construct then it is first transformed so that it is broadcastable to the data being assigned to. This is done by using the metadata constructs of the two field constructs to create a mapping of physically identical dimensions between the fields, and then manipulating the dimensions of other field construct’s data to ensure that they are broadcastable. If either of the field constructs does not have sufficient metadata to create such a mapping then an exception will be raised. In this case, any manipulation of the dimensions must be done manually, and the Data instance of construct (rather than the field construct itself) may be used for the condition.

Parameter example:

If field construct f has shape (5, 3) and g = f.transpose() < 0 then f.where(g, x=-999) will set all data values that are less than zero to -999, provided there are sufficient metadata for the data dimensions to be mapped. However, f.where(g.data, x=-999) will always fail in this example, because the shape of the condition is (3, 5), which does not broadcast to the shape of the f.

x, y: optional

Specify the assignment values. Where the condition evaluates to True, assign to the field construct’s data from x, and where the condition evaluates to False, assign to the field construct’s data from y. The x and y parameters are each one of:

  • None. The appropriate data elements array are unchanged. This the default.
  • Any scalar or array-like object (such as a numpy, Data or Field object) that is broadcastable to the shape of the data.
Parameter example:

f.where(condition), for any condition, returns a field construct with identical data values.

Parameter example:

f.where(cf.lt(0), x=-f.data, y=cf.masked) will change the sign of all negative data values, and set all other data values to missing data.

If x or y is another field construct then it is first transformed so that its data is broadcastable to the data being assigned to. This is done by using the metadata constructs of the two field constructs to create a mapping of physically identical dimensions between the fields, and then manipulating the dimensions of other field construct’s data to ensure that they are broadcastable. If either of the field constructs does not have sufficient metadata to create such a mapping then an exception will be raised. In this case, any manipulation of the dimensions must be done manually, and the Data instance of x or y (rather than the field construct itself) may be used for the condition.

Parameter example:

If field construct f has shape (5, 3) and g = f.transpose() * 10 then f.where(cf.lt(0), x=g) will set all data values that are less than zero to the equivalent elements of field construct g, provided there are sufficient metadata for the data dimensions to be mapped. However, f.where(cf.lt(0), x=g.data) will always fail in this example, because the shape of the condition is (3, 5), which does not broadcast to the shape of the f.

construct: str, optional

Define the condition by applying the construct parameter to the given metadata construct’s data, rather then the data of the field construct. Must be

  • The identity or key of a metadata coordinate construct that has data.

The construct parameter selects the metadata construct that is returned by this call of the field construct’s construct method: f.construct(construct). See cf.Field.construct for details.

Parameter example:

f.where(cf.wi(-30, 30), x=cf.masked, construct='latitude') will set all data values within 30 degrees of the equator to missing data.

inplace: bool, optional

If True then do the operation in-place and return None.

i: deprecated at version 3.0.0

Use the inplace parameter instead.

item: deprecated at version 3.0.0

Use the constuct parameter instead.

item_options: deprecated at version 3.0.0

Returns:
Field or None

A new field construct with an updated data array, or None if the operation was in-place.

Examples:

Set data array values to 15 everywhere:

>>> f.where(True, 15)

This example could also be done with subspace assignment:

>>> f[...] = 15

Set all negative data array values to zero and leave all other elements unchanged:

>>> g = f.where(f<0, 0)

Multiply all positive data array elements by -1 and set other data array elements to 3.14:

>>> g = f.where(f>0, -f, 3.14)

Set all values less than 280 and greater than 290 to missing data:

>>> g = f.where((f < 280) | (f > 290), cf.masked)

This example could also be done with a Query object:

>>> g = f.where(cf.wo(280, 290), cf.masked)

or equivalently:

>>> g = f.where(f==cf.wo(280, 290), cf.masked)

Set data array elements in the northern hemisphere to missing data in-place:

>>> condition = f.domain_mask(latitude=cf.ge(0))
>>> f.where(condition, cf.masked, inplace=True)

Missing data can only be changed if the mask is “soft”:

>>> f[0] = cf.masked
>>> g = f.where(True, 99)
>>> print(g[0],array)
[--]
>>> f.hardmask = False
>>> g = f.where(True, 99)
>>> print(g[0],array)
[99]

This in-place example could also be done with subspace assignment by indices:

>>> northern_hemisphere = f.indices(latitude=cf.ge(0))
>>> f.subspace[northern_hemisphere] = cf.masked

Set a polar rows to their zonal-mean values:

>>> condition = f.domain_mask(latitude=cf.set([-90, 90]))
>>> g = f.where(condition, f.collapse('longitude: mean'))