cf.Query


class cf.Query(operator, value, units=None, attr=None, exact=True, rtol=None, atol=None, open_lower=False, open_upper=False)[source]

Bases: object

Encapsulate a condition for subsequent evaluation.

A condition that may be applied to any object may be stored in a Query object. A Query object encapsulates a condition, such as “strictly less than 3”. When applied to an object, via its evaluate method or the Python == operator, the condition is evaluated in the context of that object.

>>> c = cf.Query('lt', 3)
>>> c
<CF Query: (lt 3)>
>>> c.evaluate(2)
True
>>> c == 2
True
>>> c != 2
False
>>> c.evaluate(3)
False
>>> c == cf.Data([1, 2, 3])
<CF Data(3): [True, True, False]>
>>> c == numpy.array([1, 2, 3])
array([True, True, False])

The following operators are supported when constructing Query instances:

Operator

Description

'lt'

A “strictly less than” condition

'le'

A “less than or equal” condition

'gt'

A “strictly greater than” condition

'ge'

A “greater than or equal” condition

'eq'

An “equal” condition

'ne'

A “not equal” condition

'wi'

A “within a range” condition

'wo'

A “without a range” condition

'set'

A “member of set” condition

'isclose'

An “is close” condition

Compound queries

Multiple conditions may be combined with the Python bitwise “and” (&) and “or” (|) operators to form a new Query object.

>>> ge3 = cf.Query('ge', 3)
>>> lt5 = cf.Query('lt', 5)
>>> c = ge3 & lt5
>>> c
<CF Query: [(ge 3) & (lt 5)]>
>>> c == 2
False
>>> c != 2
True
>>> c = ge3 | lt5
>>> c
<CF Query: [(ge 3) | (lt 5)]>
>>> c == 2
True
>>> c &= cf.Query('set', [1, 3, 5])
>>> c
<CF Query: [[(ge 3) | (lt 5)] & (set [1, 3, 5])]>
>>> c == 2
False
>>> c == 3
True

A condition can be applied to an attribute of an object.

>>> upper_bounds_ge_minus4 = cf.Query('ge', -4, attr='upper_bounds')
>>> x
<CF DimensionCoordinate: grid_longitude(9) degrees>
>>> print(x.bounds.array)
[[-4.92 -4.48]
 [-4.48 -4.04]
 [-4.04 -3.6 ]
 [-3.6  -3.16]
 [-3.16 -2.72]
 [-2.72 -2.28]
 [-2.28 -1.84]
 [-1.84 -1.4 ]
 [-1.4  -0.96]]
>>> print((upper_bounds_ge_minus4 == x).array)
[False False  True  True  True  True  True  True  True]
>>> upper_bounds_ge_minus4 = cf.Query('ge', -4, attr='upper_bounds')

A condition can also be applied to attributes of attributes of an object.

>>> t
<CF DimensionCoordinate: time(4) >
>>> t.lower_bounds.month.array
array([12,  3,  6,  9])
>>> c = cf.Query('ge', 8, attr='lower_bounds.month')
>>> c == t
<CF Data(4): [True, ..., True]>
>>> (c == t).array
array([ True,  False, False, True])

The query interface

In general, the query operator must be permitted between the value of the condition and the operand for which it is being evaluated. For example, when the value is an int, the query works if the operand is also an int, but fails if it is a list:

>>> c = cf.Query('lt', 2)
>>> c == 1
True
>>> c == [1, 2, 3]
TypeError: '<' not supported between instances of 'list' and 'int'

This behaviour is overridden if the operand has an appropriate “query interface” method. When such a method exists, it is used instead of the equivalent built-in Python operator.

Query interface method

Description

__query_lt__

Called when a 'lt' condition is evaluated

__query_le__

Called when a 'le' condition is evaluated

__query_gt__

Called when a 'gt' condition is evaluated

__query_ge__

Called when a 'ge' condition is evaluated

__query_eq__

Called when an 'eq' condition is evaluated

__query_ne__

Called when a 'ne' condition is evaluated

__query_wi__

Called when a 'wi' condition is evaluated

__query_wo__

Called when a 'wo' condition is evaluated

__query_set__

Called when a 'set' condition is evaluated

__query_isclose__

Called when an 'isclose' condition is evaluated.

In general, each method must have the query value as it’s only parameter. The only exception is for __query_isclose__, which also requires the absolute and relative numerical tolerances to be provided.

When the condition is on an attribute, or nested attributes, of the operand, the query interface method is looked for on the attribute object, rather than the parent object.

If the value has units then the argument passed to query interface method is automatically a Data object that attaches the units to the value.

For example:

>>> class myList(list):
...     pass
...
>>> class myList_with_interface(list):
...     def __query_lt__(self, value):
...         return type(self)([x < value for x in self])
...
>>> c == myList([1, 2, 3])
TypeError: '<' not supported between instances of 'myList' and 'int'
>>> c == myList_with_interface([1, 2, 3])
[True, False, False]

Initialisation

Parameters
operator: str

The query operator.

value:

The value of the condition.

units: str or Units, optional

The units of value. By default, the same units as the operand being tested are assumed, if applicable. If units is specified and value already has units (such as those attached to a Data object), then the pair of units must be equivalent.

attr: str, optional

Apply the condition to the attribute, or nested attributes, of the operand, rather than the operand itself. Nested attributes are specified by separating them with a .. For example, the “month” attribute of the “bounds” attribute is specified as 'bounds.month'. See also the addattr method.

rtol: number, optional

Only applicable to the 'isclose' operator. The tolerance on relative numerical differences. If None, the default, then the value returned by cf.rtol is used at evaluation time.

New in version 3.15.2.

atol: number, optional

Only applicable to the 'isclose' operator. The tolerance on absolute numerical differences. If None, the default, then the value returned by cf.atol is used at evaluation time.

New in version 3.15.2.

open_lower: bool, optional

Only applicable to the 'wi' operator. If True, open the interval at the lower bound so that value0 is excluded from the range. By default the interval is closed so that value0 is included.

New in version 3.16.2.

open_upper: bool, optional

Only applicable to the 'wi' operator. If True, open the interval at the upper bound so that value1 is excluded from the range. By default the interval is closed so that value1 is included.

New in version 3.16.2.

exact: deprecated at version 3.0.0.

Use re.compile objects in value instead.

Methods

addattr

Redefine the query to be on an object’s attribute.

copy

Return a deep copy.

dump

Return a string containing a full description of the instance.

equals

True if two Query objects are the same.

equivalent

Deprecated at version 3.0.0.

evaluate

Evaluate the query operation for a given left hand side operand.

exact

Deprecated at version 3.0.0.

inspect

Inspect the object for debugging.

set_condition_units

Set units of condition values in-place.

setdefault

Set condition parameters in-place that are not already set.

Attributes

attr

The object attribute on which to apply the query condition.

operator

The query operator.

value

The value of the condition encapsulated by the query.

iscontains

Return True if the query is a “cell contains” condition.

isquery

Units

Return the units of the query.

atol

The tolerance on absolute numerical differences.

rtol

The tolerance on relative numerical differences.

open_upper

True if the interval is open at the (excludes the) upper bound.

open_lower

True if the interval is open at the (excludes the) lower bound.

Special

Methods

__deepcopy__

Used if copy.deepcopy is called on the variable.

__repr__

Called by the repr built-in function.

__str__

Called by the str built-in function.

__eq__

The rich comparison operator ==

__ne__

The rich comparison operator !=

__and__

The binary bitwise operation &

__iand__

The augmented bitwise assignment &=

__or__

The binary bitwise operation |

__ior__

The augmented bitwise assignment |=

__dask_tokenize__

Return a hashable value fully representative of the object.