From 40254fccf9def93a6a24fe3c9161bbaabd3df479 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Sun, 3 Sep 2023 10:46:04 +0100 Subject: [PATCH] Squeeze attribute data --- cdflib/cdfread.py | 8 ++++++-- cdflib/utils.py | 9 +++++++++ cdflib/xarray/cdf_to_xarray.py | 2 +- doc/changelog.rst | 6 ++++-- tests/test_cdfwrite.py | 8 ++++---- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/cdflib/cdfread.py b/cdflib/cdfread.py index 8003d48..ced85ee 100644 --- a/cdflib/cdfread.py +++ b/cdflib/cdfread.py @@ -9,6 +9,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union import numpy as np +import numpy.typing as npt import cdflib.epochs as epoch from cdflib._gzip_wrapper import gzip_inflate @@ -23,6 +24,7 @@ VDRInfo, ) from cdflib.s3 import S3object +from cdflib.utils import _squeeze_or_scalar __all__ = ["CDF"] @@ -1770,14 +1772,16 @@ def _get_attdata(self, adr_info: ADRInfo, entry_num: int, num_entry: int, first_ data_type = self._datatype_token(aedr_info.data_type) num_items = aedr_info.num_elements - data = aedr_info.entry + data: Union[str, npt.NDArray] = aedr_info.entry if isinstance(data, str): if aedr_info.num_strings is not None: num_strings = aedr_info.num_strings num_items = num_strings if num_strings > 1 and isinstance(aedr_info.entry, str): data = np.array(aedr_info.entry.split("\\N ")) - return AttData(item_size, data_type, num_items, data) + return AttData(item_size, data_type, num_items, data) + else: + return AttData(item_size, data_type, num_items, _squeeze_or_scalar(data)) else: position = next_aedr diff --git a/cdflib/utils.py b/cdflib/utils.py index 709097c..894c13b 100644 --- a/cdflib/utils.py +++ b/cdflib/utils.py @@ -1,9 +1,18 @@ +from numbers import Number from typing import Union import numpy as np import numpy.typing as npt +def _squeeze_or_scalar(arr: npt.ArrayLike) -> Union[npt.NDArray, Number]: + arr = np.squeeze(arr) + if arr.ndim == 0: + return arr.item() + else: + return arr + + def _squeeze_or_scalar_real(arr: npt.ArrayLike) -> Union[npt.NDArray, float]: arr = np.squeeze(arr) if arr.ndim == 0: diff --git a/cdflib/xarray/cdf_to_xarray.py b/cdflib/xarray/cdf_to_xarray.py index 2fa386b..72a7acf 100644 --- a/cdflib/xarray/cdf_to_xarray.py +++ b/cdflib/xarray/cdf_to_xarray.py @@ -69,7 +69,7 @@ def _convert_cdf_time_types( for att in atts: data_type = atts[att].Data_Type data = atts[att].Data - if len(data) == 0 or data_type not in ("CDF_EPOCH", "CDF_EPOCH16", "CDF_TIME_TT2000"): + if data_type not in ("CDF_EPOCH", "CDF_EPOCH16", "CDF_TIME_TT2000"): new_atts[att] = data else: if to_datetime: diff --git a/doc/changelog.rst b/doc/changelog.rst index 3b326ea..67fa88a 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -2,8 +2,10 @@ Changelog ========= -Unreleased -========== +1.2.0 +===== +- Attribute data with a single value is now returned as a Python scalar instead of + a numpy array. - Added missing changelog entries for 1.1.1 and 1.1.2. 1.1.2 diff --git a/tests/test_cdfwrite.py b/tests/test_cdfwrite.py index e54c290..1391926 100755 --- a/tests/test_cdfwrite.py +++ b/tests/test_cdfwrite.py @@ -82,7 +82,7 @@ def test_checksum_compressed(tmp_path): np.testing.assert_equal(var, v) att = reader.attget("Attribute1", entry=0) - assert att.Data == [1] + assert att.Data == 1 att = reader.attget("Attribute2", entry=0) assert att.Data == "500" @@ -265,7 +265,7 @@ def test_create_zvariables_with_attributes(tmp_path): # Test CDF info att = reader.attget("Attribute1", entry=0) - assert att.Data == [1] + assert att.Data == 1 att = reader.attget("Attribute2", entry=1) assert att.Data == "1000" @@ -300,7 +300,7 @@ def test_create_zvariables_then_attributes(tmp_path): # Test CDF info att = reader.attget("Attribute1", entry=0) - assert att.Data == [1] + assert att.Data == 1 att = reader.attget("Attribute2", entry=1) att.Data == "1000" @@ -567,7 +567,7 @@ def test_create_2d_r_and_z_variables(tmp_path): np.testing.assert_equal(var, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) att = reader.attget("Attribute1", entry="Variable2") - assert att.Data == [2] + assert att.Data == 2 att = reader.attget("Attribute2", entry="Variable2") assert att.Data == "1000"