Coder for CF Timedelta coding. Parameters ---------- time_unit : PDDatetimeUnitOptions Target resolution when decoding timedeltas via units. Defaults to "ns". When decoding via dtype, the resolution is specified in the dtype attribute, so this parameter is ignore
| 1472 | |
| 1473 | |
| 1474 | class CFTimedeltaCoder(VariableCoder): |
| 1475 | """Coder for CF Timedelta coding. |
| 1476 | |
| 1477 | Parameters |
| 1478 | ---------- |
| 1479 | time_unit : PDDatetimeUnitOptions |
| 1480 | Target resolution when decoding timedeltas via units. Defaults to "ns". |
| 1481 | When decoding via dtype, the resolution is specified in the dtype |
| 1482 | attribute, so this parameter is ignored. |
| 1483 | decode_via_units : bool |
| 1484 | Whether to decode timedeltas based on the presence of a timedelta-like |
| 1485 | units attribute, e.g. "seconds". Defaults to True, but in the future |
| 1486 | will default to False. |
| 1487 | decode_via_dtype : bool |
| 1488 | Whether to decode timedeltas based on the presence of an np.timedelta64 |
| 1489 | dtype attribute, e.g. "timedelta64[s]". Defaults to True. |
| 1490 | """ |
| 1491 | |
| 1492 | def __init__( |
| 1493 | self, |
| 1494 | time_unit: PDDatetimeUnitOptions | None = None, |
| 1495 | decode_via_units: bool = False, |
| 1496 | decode_via_dtype: bool = True, |
| 1497 | ) -> None: |
| 1498 | self.time_unit = time_unit |
| 1499 | self.decode_via_units = decode_via_units |
| 1500 | self.decode_via_dtype = decode_via_dtype |
| 1501 | |
| 1502 | def encode(self, variable: Variable, name: T_Name = None) -> Variable: |
| 1503 | if np.issubdtype(variable.dtype, np.timedelta64): |
| 1504 | dims, data, attrs, encoding = unpack_for_encoding(variable) |
| 1505 | dtype = encoding.get("dtype", None) |
| 1506 | units = encoding.pop("units", None) |
| 1507 | |
| 1508 | # in the case of packed data we need to encode into |
| 1509 | # float first, the correct dtype will be established |
| 1510 | # via CFScaleOffsetCoder/CFMaskCoder |
| 1511 | if "add_offset" in encoding or "scale_factor" in encoding: |
| 1512 | dtype = data.dtype if data.dtype.kind == "f" else "float64" |
| 1513 | |
| 1514 | resolution, _ = np.datetime_data(variable.dtype) |
| 1515 | attrs_dtype = f"timedelta64[{resolution}]" |
| 1516 | safe_setitem(attrs, "dtype", attrs_dtype, name=name) |
| 1517 | |
| 1518 | data, units = encode_cf_timedelta(data, units, dtype) |
| 1519 | safe_setitem(attrs, "units", units, name=name) |
| 1520 | return Variable(dims, data, attrs, encoding, fastpath=True) |
| 1521 | else: |
| 1522 | return variable |
| 1523 | |
| 1524 | def decode(self, variable: Variable, name: T_Name = None) -> Variable: |
| 1525 | units = variable.attrs.get("units", None) |
| 1526 | has_timedelta_units = isinstance(units, str) and units in TIME_UNITS |
| 1527 | has_timedelta_dtype = has_timedelta64_encoding_dtype(variable.attrs) |
| 1528 | is_dtype_decodable = has_timedelta_units and has_timedelta_dtype |
| 1529 | is_units_decodable = has_timedelta_units |
| 1530 | if (is_dtype_decodable and self.decode_via_dtype) or ( |
| 1531 | is_units_decodable and self.decode_via_units |
no outgoing calls
searching dependent graphs…