| 524 | return Variable(dims, data, attrs, encoding, fastpath=True) |
| 525 | |
| 526 | def decode(self, variable: Variable, name: T_Name = None) -> Variable: |
| 527 | _attrs = variable.attrs |
| 528 | if "scale_factor" in _attrs or "add_offset" in _attrs: |
| 529 | dims, data, attrs, encoding = unpack_for_decoding(variable) |
| 530 | |
| 531 | scale_factor = pop_to(attrs, encoding, "scale_factor", name=name) |
| 532 | add_offset = pop_to(attrs, encoding, "add_offset", name=name) |
| 533 | if duck_array_ops.ndim(scale_factor) > 0: |
| 534 | scale_factor = np.asarray(scale_factor).item() |
| 535 | if duck_array_ops.ndim(add_offset) > 0: |
| 536 | add_offset = np.asarray(add_offset).item() |
| 537 | # if we have a _FillValue/masked_value in encoding we already have the wanted |
| 538 | # floating point dtype here (via CFMaskCoder), so no check is necessary |
| 539 | # only check in other cases and for time-like |
| 540 | dtype = data.dtype |
| 541 | is_time_like = _is_time_like(attrs.get("units")) |
| 542 | if ( |
| 543 | ("_FillValue" not in encoding and "missing_value" not in encoding) |
| 544 | or (is_time_like == "datetime" and self.decode_times) |
| 545 | or (is_time_like == "timedelta" and self.decode_timedelta) |
| 546 | ): |
| 547 | dtype = _choose_float_dtype(dtype, encoding) |
| 548 | |
| 549 | transform = partial( |
| 550 | _scale_offset_decoding, |
| 551 | scale_factor=scale_factor, |
| 552 | add_offset=add_offset, |
| 553 | dtype=dtype, |
| 554 | ) |
| 555 | data = lazy_elemwise_func(data, transform, dtype) |
| 556 | |
| 557 | return Variable(dims, data, attrs, encoding, fastpath=True) |
| 558 | else: |
| 559 | return variable |
| 560 | |
| 561 | |
| 562 | class DefaultFillvalueCoder(VariableCoder): |