ntv-numpy.ntv_numpy

NTV-NumPy Package

Created on March 2024

@author: philippe@loco-labs.io

This package contains the following classes and functions:

  • ntv-numpy.ntv_numpy.numpy_ntv_connector :

    • ntv-numpy.ntv_numpy.numpy_ntv_connector.XDatasetConnec
    • ntv-numpy.ntv_numpy.numpy_ntv_connector.XndarrayConnec
    • ntv-numpy.ntv_numpy.numpy_ntv_connector.NdarrayConnec
    • ntv-numpy.ntv_numpy.numpy_ntv_connector.NarrayConnec
  • ntv-numpy.ntv_numpy.xconnector :

    • ntv-numpy.ntv_numpy.xconnector.PandasConnec
    • ntv-numpy.ntv_numpy.xconnector.XarrayConnec
    • ntv-numpy.ntv_numpy.xconnector.ScippConnec
    • ntv-numpy.ntv_numpy.xconnector.AstropyNDDataConnec
  • ntv-numpy.ntv_numpy.data_array :

    • ntv-numpy.ntv_numpy.data_array.Darray
    • ntv-numpy.ntv_numpy.data_array.Dfull
    • ntv-numpy.ntv_numpy.data_array.Dcomplete
    • ntv-numpy.ntv_numpy.data_array.Dutil
  • ntv-numpy.ntv_numpy.ndarray :

    • ntv-numpy.ntv_numpy.ndarray.Ndarray
    • ntv-numpy.ntv_numpy.ndarray.Nutil
    • ntv-numpy.ntv_numpy.ndarray.NdarrayError
  • ntv-numpy.ntv_numpy.xndarray :

    • ntv-numpy.ntv_numpy.xndarray.Xndarray
  • ntv-numpy.ntv_numpy.xdataset :

    • ntv-numpy.ntv_numpy.xdataset.Xdataset
    • ntv-numpy.ntv_numpy.xdataset.XdatasetInterface
    • ntv-numpy.ntv_numpy.xdataset.XdatasetCategory
  • ntv-numpy.ntv_numpy.ndtype :

    • ntv-numpy.ntv_numpy.ndtype.Ndtype
  • ntv-numpy.ntv_numpy.xarray_accessors :

    • ntv-numpy.ntv_numpy.xarray_accessors.NxrDatasetAccessor
 1# -*- coding: utf-8 -*-
 2"""
 3***NTV-NumPy Package***
 4
 5Created on March 2024
 6
 7@author: philippe@loco-labs.io
 8
 9This package contains the following classes and functions:
10
11- `ntv-numpy.ntv_numpy.numpy_ntv_connector` :
12
13    - `ntv-numpy.ntv_numpy.numpy_ntv_connector.XDatasetConnec`
14    - `ntv-numpy.ntv_numpy.numpy_ntv_connector.XndarrayConnec`
15    - `ntv-numpy.ntv_numpy.numpy_ntv_connector.NdarrayConnec`
16    - `ntv-numpy.ntv_numpy.numpy_ntv_connector.NarrayConnec`
17
18- `ntv-numpy.ntv_numpy.xconnector` :
19
20    - `ntv-numpy.ntv_numpy.xconnector.PandasConnec`
21    - `ntv-numpy.ntv_numpy.xconnector.XarrayConnec`
22    - `ntv-numpy.ntv_numpy.xconnector.ScippConnec`
23    - `ntv-numpy.ntv_numpy.xconnector.AstropyNDDataConnec`
24
25- `ntv-numpy.ntv_numpy.data_array` :
26
27    - `ntv-numpy.ntv_numpy.data_array.Darray`
28    - `ntv-numpy.ntv_numpy.data_array.Dfull`
29    - `ntv-numpy.ntv_numpy.data_array.Dcomplete`
30    - `ntv-numpy.ntv_numpy.data_array.Dutil`
31
32- `ntv-numpy.ntv_numpy.ndarray` :
33
34    - `ntv-numpy.ntv_numpy.ndarray.Ndarray`
35    - `ntv-numpy.ntv_numpy.ndarray.Nutil`
36    - `ntv-numpy.ntv_numpy.ndarray.NdarrayError`
37
38- `ntv-numpy.ntv_numpy.xndarray` :
39
40    - `ntv-numpy.ntv_numpy.xndarray.Xndarray`
41
42- `ntv-numpy.ntv_numpy.xdataset` :
43
44    - `ntv-numpy.ntv_numpy.xdataset.Xdataset`
45    - `ntv-numpy.ntv_numpy.xdataset.XdatasetInterface`
46    - `ntv-numpy.ntv_numpy.xdataset.XdatasetCategory`
47
48- `ntv-numpy.ntv_numpy.ndtype` :
49
50    - `ntv-numpy.ntv_numpy.ndtype.Ndtype`
51
52
53- `ntv-numpy.ntv_numpy.xarray_accessors` :
54
55    - `ntv-numpy.ntv_numpy.xarray_accessors.NxrDatasetAccessor`
56"""
57
58from ntv_numpy.numpy_ntv_connector import XndarrayConnec, NdarrayConnec
59from ntv_numpy.data_array import Dfull, Dcomplete, Darray, Dutil
60from ntv_numpy.ndarray import Ndarray, Nutil
61from ntv_numpy.xndarray import Xndarray
62from ntv_numpy.xdataset import Xdataset
63
64import ntv_numpy.xarray_accessors as xarray_accessors
65
66__all__ = [
67    "XndarrayConnec",
68    "NdarrayConnec",
69    "Dfull",
70    "Dcomplete",
71    "Darray",
72    "Dutil",
73    "Ndarray",
74    "Nutil",
75    "Xndarray",
76    "Xdataset",
77    "xarray_accessors",
78]
class XndarrayConnec(json_ntv.ntv_util.NtvConnector):
121class XndarrayConnec(NtvConnector):
122    """NTV connector for Xndarray."""
123
124    clas_obj = "Xndarray"
125    clas_typ = "xndarray"
126
127    @staticmethod
128    def to_obj_ntv(ntv_value, **kwargs):
129        """convert json ntv_value into a Xndarray.
130
131        *Parameters*
132
133        - **convert** : boolean (default True) - If True, convert json data with
134        non-umpy ntv_type into Xndarray with python type
135        """
136        print(ntv_value)
137        return Xndarray.read_json(ntv_value, **kwargs)
138
139    @staticmethod
140    def to_json_ntv(value, name=None, typ=None, **kwargs):
141        """convert a Xndarray (value) into NTV json (json-value, name, ntv_type).
142
143        *Parameters*
144
145        - **typ** : string (default None) - not used,
146        - **name** : string (default None) - not used
147        - **value** : Xndarray values
148        - **encoded** : Boolean (default False) - json-value if False else json-text
149        - **header** : Boolean (default True) - including xndarray type
150        - **notype** : Boolean (default False) - including data type if False
151        - **novalue** : Boolean (default False) - including value if False
152        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
153        - **format** : string (default 'full') - representation format of the ndarray,
154        - **extension** : string (default None) - type extension
155        """
156        option = {
157            "notype": False,
158            "extension": None,
159            "format": "full",
160            "noshape": True,
161            "header": True,
162            "encoded": False,
163            "novalue": False,
164            "noname": False,
165        } | kwargs
166        if option["format"] not in ["full", "complete"]:
167            option["noshape"] = False
168        return (value.to_json(**option), name, "xndarray")

NTV connector for Xndarray.

clas_obj = 'Xndarray'
clas_typ = 'xndarray'
@staticmethod
def to_obj_ntv(ntv_value, **kwargs):
127    @staticmethod
128    def to_obj_ntv(ntv_value, **kwargs):
129        """convert json ntv_value into a Xndarray.
130
131        *Parameters*
132
133        - **convert** : boolean (default True) - If True, convert json data with
134        non-umpy ntv_type into Xndarray with python type
135        """
136        print(ntv_value)
137        return Xndarray.read_json(ntv_value, **kwargs)

convert json ntv_value into a Xndarray.

Parameters

  • convert : boolean (default True) - If True, convert json data with non-umpy ntv_type into Xndarray with python type
@staticmethod
def to_json_ntv(value, name=None, typ=None, **kwargs):
139    @staticmethod
140    def to_json_ntv(value, name=None, typ=None, **kwargs):
141        """convert a Xndarray (value) into NTV json (json-value, name, ntv_type).
142
143        *Parameters*
144
145        - **typ** : string (default None) - not used,
146        - **name** : string (default None) - not used
147        - **value** : Xndarray values
148        - **encoded** : Boolean (default False) - json-value if False else json-text
149        - **header** : Boolean (default True) - including xndarray type
150        - **notype** : Boolean (default False) - including data type if False
151        - **novalue** : Boolean (default False) - including value if False
152        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
153        - **format** : string (default 'full') - representation format of the ndarray,
154        - **extension** : string (default None) - type extension
155        """
156        option = {
157            "notype": False,
158            "extension": None,
159            "format": "full",
160            "noshape": True,
161            "header": True,
162            "encoded": False,
163            "novalue": False,
164            "noname": False,
165        } | kwargs
166        if option["format"] not in ["full", "complete"]:
167            option["noshape"] = False
168        return (value.to_json(**option), name, "xndarray")

convert a Xndarray (value) into NTV json (json-value, name, ntv_type).

Parameters

  • typ : string (default None) - not used,
  • name : string (default None) - not used
  • value : Xndarray values
  • encoded : Boolean (default False) - json-value if False else json-text
  • header : Boolean (default True) - including xndarray type
  • notype : Boolean (default False) - including data type if False
  • novalue : Boolean (default False) - including value if False
  • noshape : Boolean (default True) - if True, without shape if dim < 1
  • format : string (default 'full') - representation format of the ndarray,
  • extension : string (default None) - type extension
Inherited Members
json_ntv.ntv_util.NtvConnector
DIC_NTV_CL
DIC_GEO_CL
DIC_DAT_CL
DIC_FCT
DIC_GEO
DIC_CBOR
DIC_OBJ
castable
dic_obj
dic_type
connector
dic_connec
cast
uncast
is_json_class
is_json
keysfromderkeys
encode_coef
keysfromcoef
format_field
init_ntv_keys
class NdarrayConnec(json_ntv.ntv_util.NtvConnector):
 76class NdarrayConnec(NtvConnector):
 77    """NTV connector for Ndarray."""
 78
 79    clas_obj = "Ndarray"
 80    clas_typ = "ndarray"
 81
 82    @staticmethod
 83    def to_obj_ntv(ntv_value, **kwargs):
 84        """convert json ntv_value into a Ndarray.
 85
 86        *Parameters*
 87
 88        - **convert** : boolean (default True) - If True, convert json data with
 89        non-Numpy ntv_type into data with python type"""
 90        return Ndarray.read_json(ntv_value, **kwargs)
 91
 92    @staticmethod
 93    def to_json_ntv(value, name=None, typ=None, **kwargs):
 94        """convert a Ndarray (value, name, type) into NTV json (json-value, name, ntv_type).
 95
 96        *Parameters*
 97
 98        - **typ** : string (default None) - ntv_type of the ndarray object,
 99        - **name** : string (default None) - name of the ndarray object
100        - **value** : Ndarray value (or np.ndarray value)
101        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
102        - **notype** : Boolean (default False) - including data type if False
103        - **novalue** : Boolean (default False) - including value if False
104        - **format** : string (default 'full') - representation format of the ndarray,
105        - **encoded** : Boolean (default False) - json-value if False else json-text
106        - **header** : Boolean (default True) - including ndarray type
107        """
108        option = {
109            "format": "full",
110            "header": True,
111            "encoded": False,
112            "notype": False,
113            "noshape": True,
114            "novalue": False,
115        } | kwargs
116        if option["format"] not in ["full", "complete"]:
117            option["noshape"] = False
118        return (Ndarray(value).to_json(**option), name, "ndarray")

NTV connector for Ndarray.

clas_obj = 'Ndarray'
clas_typ = 'ndarray'
@staticmethod
def to_obj_ntv(ntv_value, **kwargs):
82    @staticmethod
83    def to_obj_ntv(ntv_value, **kwargs):
84        """convert json ntv_value into a Ndarray.
85
86        *Parameters*
87
88        - **convert** : boolean (default True) - If True, convert json data with
89        non-Numpy ntv_type into data with python type"""
90        return Ndarray.read_json(ntv_value, **kwargs)

convert json ntv_value into a Ndarray.

Parameters

  • convert : boolean (default True) - If True, convert json data with non-Numpy ntv_type into data with python type
@staticmethod
def to_json_ntv(value, name=None, typ=None, **kwargs):
 92    @staticmethod
 93    def to_json_ntv(value, name=None, typ=None, **kwargs):
 94        """convert a Ndarray (value, name, type) into NTV json (json-value, name, ntv_type).
 95
 96        *Parameters*
 97
 98        - **typ** : string (default None) - ntv_type of the ndarray object,
 99        - **name** : string (default None) - name of the ndarray object
100        - **value** : Ndarray value (or np.ndarray value)
101        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
102        - **notype** : Boolean (default False) - including data type if False
103        - **novalue** : Boolean (default False) - including value if False
104        - **format** : string (default 'full') - representation format of the ndarray,
105        - **encoded** : Boolean (default False) - json-value if False else json-text
106        - **header** : Boolean (default True) - including ndarray type
107        """
108        option = {
109            "format": "full",
110            "header": True,
111            "encoded": False,
112            "notype": False,
113            "noshape": True,
114            "novalue": False,
115        } | kwargs
116        if option["format"] not in ["full", "complete"]:
117            option["noshape"] = False
118        return (Ndarray(value).to_json(**option), name, "ndarray")

convert a Ndarray (value, name, type) into NTV json (json-value, name, ntv_type).

Parameters

  • typ : string (default None) - ntv_type of the ndarray object,
  • name : string (default None) - name of the ndarray object
  • value : Ndarray value (or np.ndarray value)
  • noshape : Boolean (default True) - if True, without shape if dim < 1
  • notype : Boolean (default False) - including data type if False
  • novalue : Boolean (default False) - including value if False
  • format : string (default 'full') - representation format of the ndarray,
  • encoded : Boolean (default False) - json-value if False else json-text
  • header : Boolean (default True) - including ndarray type
Inherited Members
json_ntv.ntv_util.NtvConnector
DIC_NTV_CL
DIC_GEO_CL
DIC_DAT_CL
DIC_FCT
DIC_GEO
DIC_CBOR
DIC_OBJ
castable
dic_obj
dic_type
connector
dic_connec
cast
uncast
is_json_class
is_json
keysfromderkeys
encode_coef
keysfromcoef
format_field
init_ntv_keys
class Dfull(ntv-numpy.ntv_numpy.Darray):
143class Dfull(Darray):
144    """Representation of a one dimensional Array with full representation
145
146    *dynamic values (@property)*
147    - `values`
148
149    *methods*
150    - `read_json` (staticmethod)
151    - `to_json`
152    """
153
154    def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False):
155        """Dfull constructor.
156
157        *Parameters*
158
159        - **data**: list, Darray or np.ndarray - data to represent (after coding)
160        - **ref** : unused
161        - **coding**: unused
162        - **dtype**: string (default None) - numpy.dtype to apply
163        """
164        super().__init__(data, dtype=dtype, unidim=unidim)
165
166    def to_json(self):
167        """return a JsonValue of the Dfull entity."""
168        return Dutil.list_json(self.data)
169
170    @property
171    def values(self):
172        """return the list of values"""
173        return self.data
174
175    @property
176    def _len_val(self):
177        """return the length of the Dfull entity"""
178        return len(self.data) if self.data.ndim > 0 else 0

Representation of a one dimensional Array with full representation

dynamic values (@property)

methods

Dfull(data, ref=None, coding=None, dtype=None, unidim=False)
154    def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False):
155        """Dfull constructor.
156
157        *Parameters*
158
159        - **data**: list, Darray or np.ndarray - data to represent (after coding)
160        - **ref** : unused
161        - **coding**: unused
162        - **dtype**: string (default None) - numpy.dtype to apply
163        """
164        super().__init__(data, dtype=dtype, unidim=unidim)

Dfull constructor.

Parameters

  • data: list, Darray or np.ndarray - data to represent (after coding)
  • ref : unused
  • coding: unused
  • dtype: string (default None) - numpy.dtype to apply
def to_json(self):
166    def to_json(self):
167        """return a JsonValue of the Dfull entity."""
168        return Dutil.list_json(self.data)

return a JsonValue of the Dfull entity.

values
170    @property
171    def values(self):
172        """return the list of values"""
173        return self.data

return the list of values

Inherited Members
Darray
ref
coding
read_json
class Dcomplete(ntv-numpy.ntv_numpy.Darray):
181class Dcomplete(Darray):
182    """Representation of a one dimensional Array with full representation
183
184    *dynamic values (@property)*
185    - `values`
186
187    *methods*
188    - `read_json` (staticmethod)
189    - `to_json`
190    """
191
192    def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False):
193        """Dcomplete constructor.
194
195        *Parameters*
196
197        - **data**: list, Darray or np.ndarray - data to represent (after coding)
198        - **ref** : unused
199        - **coding**: List of integer (default None) - mapping between data and the list of values
200        - **dtype**: string (default None) - numpy.dtype to apply
201        """
202        if coding is None:
203            try:
204                data, coding = np.unique(data, return_inverse=True)
205            except (TypeError, ValueError):
206                dat, idx, coding = np.unique(
207                    np.frompyfunc(Ntv.from_obj, 1, 1)(data),
208                    return_index=True,
209                    return_inverse=True,
210                )
211                data = data[idx]
212        super().__init__(data, coding=coding, dtype=dtype, unidim=unidim)
213
214    def to_json(self):
215        """return a JsonValue of the Dcomplete entity."""
216        return [Dutil.list_json(self.data), self.coding.tolist()]
217
218    @property
219    def values(self):
220        """return the list of values"""
221        return self.data[self.coding]
222
223    @property
224    def _len_val(self):
225        """return the length of the Dcomplete entity"""
226        return len(self.coding) if self.coding.ndim > 0 else 0

Representation of a one dimensional Array with full representation

dynamic values (@property)

methods

Dcomplete(data, ref=None, coding=None, dtype=None, unidim=False)
192    def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False):
193        """Dcomplete constructor.
194
195        *Parameters*
196
197        - **data**: list, Darray or np.ndarray - data to represent (after coding)
198        - **ref** : unused
199        - **coding**: List of integer (default None) - mapping between data and the list of values
200        - **dtype**: string (default None) - numpy.dtype to apply
201        """
202        if coding is None:
203            try:
204                data, coding = np.unique(data, return_inverse=True)
205            except (TypeError, ValueError):
206                dat, idx, coding = np.unique(
207                    np.frompyfunc(Ntv.from_obj, 1, 1)(data),
208                    return_index=True,
209                    return_inverse=True,
210                )
211                data = data[idx]
212        super().__init__(data, coding=coding, dtype=dtype, unidim=unidim)

Dcomplete constructor.

Parameters

  • data: list, Darray or np.ndarray - data to represent (after coding)
  • ref : unused
  • coding: List of integer (default None) - mapping between data and the list of values
  • dtype: string (default None) - numpy.dtype to apply
def to_json(self):
214    def to_json(self):
215        """return a JsonValue of the Dcomplete entity."""
216        return [Dutil.list_json(self.data), self.coding.tolist()]

return a JsonValue of the Dcomplete entity.

values
218    @property
219    def values(self):
220        """return the list of values"""
221        return self.data[self.coding]

return the list of values

Inherited Members
Darray
ref
coding
read_json
class Darray(abc.ABC):
 24class Darray(ABC):
 25    """The Darray class is an abstract class used by `Dfull`and `Dcomplete` classes.
 26
 27    *Attributes :*
 28    - **data** :  np.ndarray - data after coding
 29    - **ref**:  int or string - reference to another Darray data
 30    - **coding**: np.ndarray of int - mapping between data and the values
 31
 32    *dynamic values (@property)*
 33    - `values`
 34
 35    *methods*
 36    - `read_json` (staticmethod)
 37    - `to_json`
 38    """
 39
 40    def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False):
 41        """Darray constructor.
 42
 43        *Parameters*
 44
 45        - **data**: list, Darray or np.ndarray - data to represent (after coding)
 46        - **ref** : String or integer (default None) - name or index of another Darray
 47        - **coding**: List of integer (default None) - mapping between data and the list of values
 48        - **dtype**: string (default None) - numpy.dtype to apply
 49        """
 50        if isinstance(data, Darray):
 51            self.data = data.data
 52            self.ref = data.ref
 53            self.coding = data.coding
 54            return
 55        data = data if isinstance(data, (list, np.ndarray)) else [data]
 56        if (len(data) > 0 and isinstance(data[0], (list, np.ndarray))) or unidim:
 57            dtype = data.dtype if isinstance(data, np.ndarray) else "object"
 58            self.data = np.fromiter(data, dtype=dtype)
 59        else:
 60            self.data = np.array(data, dtype=dtype).reshape(-1)
 61        self.ref = ref
 62        self.coding = np.array(coding)
 63
 64    def __repr__(self):
 65        """return classname and number of value"""
 66        return self.__class__.__name__ + "[" + str(len(self)) + "]"
 67
 68    def __str__(self):
 69        """return json string format"""
 70        return json.dumps(self.to_json())
 71
 72    def __eq__(self, other):
 73        """equal if values are equal"""
 74        return np.array_equal(self.values, other.values, equal_nan=False)
 75
 76    def __len__(self):
 77        """len of values"""
 78        return self._len_val
 79
 80    def __contains__(self, item):
 81        """item of values"""
 82        return item in self.values
 83
 84    def __getitem__(self, ind):
 85        """return value item"""
 86        if isinstance(ind, tuple):
 87            return [self.values[i] for i in ind]
 88            # return [copy(self.values[i]) for i in ind]
 89        return self.values[ind]
 90        # return copy(self.values[ind])
 91
 92    def __copy__(self):
 93        """Copy all the data"""
 94        return self.__class__(self)
 95
 96    @staticmethod
 97    def read_json(val, dtype=None, unidim=False):
 98        """return a Darray entity from a list of data.
 99
100        *Parameters*
101
102        - **val**: list of data
103        - **dtype** : string (default None) - numpy.dtype to apply
104        """
105        val = val if isinstance(val, list) else [val]
106        if not val or not isinstance(val[0], list):
107            return Dfull(val, dtype=dtype, unidim=unidim)
108        match val:
109            case [data, ref, list(coding)] if (
110                isinstance(ref, (int, str))
111                and isinstance(coding[0], int)
112                and max(coding) < len(data)
113            ):
114                return None
115            case [data, ref] if (
116                isinstance(data, list) and isinstance(ref, (int, str))
117            ):
118                return None
119            case [data, list(coef)] if len(coef) == 1:
120                return None
121            case [data, list(coding)] if (
122                isinstance(coding[0], int) and max(coding) < len(data)
123            ):
124                return Dcomplete(data, None, coding, dtype=dtype, unidim=unidim)
125            case _:
126                return Dfull(val, dtype=dtype, unidim=unidim)
127
128    @abstractmethod
129    def to_json(self):
130        """return a JsonValue"""
131
132    @property
133    @abstractmethod
134    def values(self):
135        """return the list of values"""
136
137    @property
138    @abstractmethod
139    def _len_val(self):
140        """return the length of the entity"""

The Darray class is an abstract class used by Dfulland Dcomplete classes.

Attributes :

  • data : np.ndarray - data after coding
  • ref: int or string - reference to another Darray data
  • coding: np.ndarray of int - mapping between data and the values

dynamic values (@property)

methods

Darray(data, ref=None, coding=None, dtype=None, unidim=False)
40    def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False):
41        """Darray constructor.
42
43        *Parameters*
44
45        - **data**: list, Darray or np.ndarray - data to represent (after coding)
46        - **ref** : String or integer (default None) - name or index of another Darray
47        - **coding**: List of integer (default None) - mapping between data and the list of values
48        - **dtype**: string (default None) - numpy.dtype to apply
49        """
50        if isinstance(data, Darray):
51            self.data = data.data
52            self.ref = data.ref
53            self.coding = data.coding
54            return
55        data = data if isinstance(data, (list, np.ndarray)) else [data]
56        if (len(data) > 0 and isinstance(data[0], (list, np.ndarray))) or unidim:
57            dtype = data.dtype if isinstance(data, np.ndarray) else "object"
58            self.data = np.fromiter(data, dtype=dtype)
59        else:
60            self.data = np.array(data, dtype=dtype).reshape(-1)
61        self.ref = ref
62        self.coding = np.array(coding)

Darray constructor.

Parameters

  • data: list, Darray or np.ndarray - data to represent (after coding)
  • ref : String or integer (default None) - name or index of another Darray
  • coding: List of integer (default None) - mapping between data and the list of values
  • dtype: string (default None) - numpy.dtype to apply
ref
coding
@staticmethod
def read_json(val, dtype=None, unidim=False):
 96    @staticmethod
 97    def read_json(val, dtype=None, unidim=False):
 98        """return a Darray entity from a list of data.
 99
100        *Parameters*
101
102        - **val**: list of data
103        - **dtype** : string (default None) - numpy.dtype to apply
104        """
105        val = val if isinstance(val, list) else [val]
106        if not val or not isinstance(val[0], list):
107            return Dfull(val, dtype=dtype, unidim=unidim)
108        match val:
109            case [data, ref, list(coding)] if (
110                isinstance(ref, (int, str))
111                and isinstance(coding[0], int)
112                and max(coding) < len(data)
113            ):
114                return None
115            case [data, ref] if (
116                isinstance(data, list) and isinstance(ref, (int, str))
117            ):
118                return None
119            case [data, list(coef)] if len(coef) == 1:
120                return None
121            case [data, list(coding)] if (
122                isinstance(coding[0], int) and max(coding) < len(data)
123            ):
124                return Dcomplete(data, None, coding, dtype=dtype, unidim=unidim)
125            case _:
126                return Dfull(val, dtype=dtype, unidim=unidim)

return a Darray entity from a list of data.

Parameters

  • val: list of data
  • dtype : string (default None) - numpy.dtype to apply
@abstractmethod
def to_json(self):
128    @abstractmethod
129    def to_json(self):
130        """return a JsonValue"""

return a JsonValue

values
132    @property
133    @abstractmethod
134    def values(self):
135        """return the list of values"""

return the list of values

class Dutil:
229class Dutil:
230    """np.ndarray utilities.
231
232    *static methods*
233    - `convert`
234    - `is_json`
235    - `ntv_val`
236    - `add_ext`
237    - `split_type`
238    - `ntv_type`
239    - `nda_ntv_type`
240    - `dtype`
241    - `json_ntv`
242    - `split_name`
243    - `split_json_name`
244    """
245
246    @staticmethod
247    def equals(nself, nother):
248        """return True if all elements are equals and dtype are equal"""
249        if not (isinstance(nself, np.ndarray) and isinstance(nother, np.ndarray)):
250            return False
251        if nself.dtype != nother.dtype or nself.shape != nother.shape:
252            return False
253        if len(nself.shape) == 0:
254            return True
255        if len(nself) != len(nother):
256            return False
257        if len(nself) == 0:
258            return True
259        if isinstance(nself[0], (np.ndarray, pd.Series, pd.DataFrame)):
260            SeriesConnec = NtvConnector.connector().get("SeriesConnec")
261            DataFrameConnec = NtvConnector.connector().get("DataFrameConnec")
262            equal = {
263                np.ndarray: Dutil.equals,
264                pd.Series: SeriesConnec.equals,
265                pd.DataFrame: DataFrameConnec.equals,
266            }
267            for nps, npo in zip(nself, nother):
268                if not equal[type(nself[0])](nps, npo):
269                    return False
270            return True
271        return np.array_equal(nself, nother)
272
273    @staticmethod
274    def list_json(nda):
275        """return a JSON representation of a unidimensional np.ndarray"""
276        if len(nda) == 0:
277            return []
278        if isinstance(nda[0], np.ndarray):
279            return [Dutil.list_json(arr) for arr in nda]
280        return nda.tolist()

np.ndarray utilities.

static methods

  • convert
  • is_json
  • ntv_val
  • add_ext
  • split_type
  • ntv_type
  • nda_ntv_type
  • dtype
  • json_ntv
  • split_name
  • split_json_name
@staticmethod
def equals(nself, nother):
246    @staticmethod
247    def equals(nself, nother):
248        """return True if all elements are equals and dtype are equal"""
249        if not (isinstance(nself, np.ndarray) and isinstance(nother, np.ndarray)):
250            return False
251        if nself.dtype != nother.dtype or nself.shape != nother.shape:
252            return False
253        if len(nself.shape) == 0:
254            return True
255        if len(nself) != len(nother):
256            return False
257        if len(nself) == 0:
258            return True
259        if isinstance(nself[0], (np.ndarray, pd.Series, pd.DataFrame)):
260            SeriesConnec = NtvConnector.connector().get("SeriesConnec")
261            DataFrameConnec = NtvConnector.connector().get("DataFrameConnec")
262            equal = {
263                np.ndarray: Dutil.equals,
264                pd.Series: SeriesConnec.equals,
265                pd.DataFrame: DataFrameConnec.equals,
266            }
267            for nps, npo in zip(nself, nother):
268                if not equal[type(nself[0])](nps, npo):
269                    return False
270            return True
271        return np.array_equal(nself, nother)

return True if all elements are equals and dtype are equal

@staticmethod
def list_json(nda):
273    @staticmethod
274    def list_json(nda):
275        """return a JSON representation of a unidimensional np.ndarray"""
276        if len(nda) == 0:
277            return []
278        if isinstance(nda[0], np.ndarray):
279            return [Dutil.list_json(arr) for arr in nda]
280        return nda.tolist()

return a JSON representation of a unidimensional np.ndarray

class Ndarray:
 29class Ndarray:
 30    """The Ndarray class is the JSON interface of numpy.ndarrays.
 31
 32    *static methods*
 33    - `read_json`
 34    - `to_json`
 35    - `set_shape`
 36    """
 37
 38    def __init__(self, dar, ntv_type=None, shape=None, str_uri=True):
 39        """Ndarray constructor.
 40
 41        *Parameters*
 42
 43        - **dar**: Darray or np.ndarray - data to represent
 44        - **shape** : list of integer (default None) - length of dimensions
 45        - **ntv_type**: string (default None) - NTVtype to apply
 46        - **str_uri**: boolean(default True) - if True and dar is a string,
 47        dar is an uri else a np.array
 48        """
 49        dar = [None] if isinstance(dar, list) and len(dar) == 0 else dar
 50        if isinstance(dar, Ndarray):
 51            self.uri = dar.uri
 52            self.is_json = dar.is_json
 53            self.ntvtype = dar.ntvtype
 54            self.shape = dar.shape
 55            self.darray = dar.darray
 56            return
 57        if isinstance(dar, str) and str_uri:
 58            self.uri = dar
 59            self.is_json = True
 60            self.ntvtype = Ndtype(ntv_type) if ntv_type else None
 61            self.shape = shape
 62            self.darray = None
 63            return
 64        if shape:
 65            dar = Dfull(dar, dtype=Nutil.dtype(ntv_type), unidim=True).data
 66        else:
 67            dar = np.array(dar, dtype=Nutil.dtype(ntv_type))
 68            shape = list(dar.shape)
 69        dar = np.array(dar).reshape(-1)
 70        ntv_type = Nutil.nda_ntv_type(dar, ntv_type)
 71        self.uri = None
 72        self.is_json = Nutil.is_json(dar[0])
 73        self.ntvtype = Ndtype(ntv_type)
 74        self.shape = shape
 75        self.darray = dar.astype(Nutil.dtype(str(self.ntvtype)))
 76
 77    def __repr__(self):
 78        """return classname, the shape and the ntv_type"""
 79        uri = self.uri if self.uri else ""
 80        typ = self.ntv_type if self.ntv_type else ""
 81        sha = str(self.shape) if self.shape else ""
 82        u_t = ", " if uri and typ + sha else ""
 83        t_s = ", " if typ and sha else ""
 84        return self.__class__.__name__ + "(" + uri + u_t + typ + t_s + sha + ")"
 85
 86    def __str__(self):
 87        """return json string format"""
 88        return json.dumps(self.to_json())
 89
 90    def __eq__(self, other):
 91        """equal if attributes are equal"""
 92        if self.ntv_type != other.ntv_type:
 93            return False
 94        if self.uri != other.uri:
 95            return False
 96        if self.shape != other.shape:
 97            return False
 98        if self.darray is None and other.darray is None:
 99            return True
100        if self.darray is None or other.darray is None:
101            return False
102        return Dutil.equals(self.darray, other.darray)
103
104    def __len__(self):
105        """len of ndarray"""
106        return len(self.darray) if self.darray is not None else 0
107
108    def __contains__(self, item):
109        """item of darray values"""
110        return item in self.darray if self.darray is not None else None
111
112    def __getitem__(self, ind):
113        """return darray value item"""
114        if self.darray is None:
115            return None
116        if isinstance(ind, tuple):
117            return [self.darray[i] for i in ind]
118        return self.darray[ind]
119
120    def __copy__(self):
121        """Copy all the data"""
122        return self.__class__(self)
123
124    def __array__(self):
125        """numpy array interface"""
126        return self.ndarray
127
128    @property
129    def ntv_type(self):
130        """string representation of ntvtype"""
131        return str(self.ntvtype) if self.ntvtype else None
132
133    @property
134    def ndarray(self):
135        """representation with a np.ndarray not flattened"""
136        return self.darray.reshape(self.shape) if self.darray is not None else None
137
138    def set_shape(self, shape):
139        """update the shape"""
140        if Ndarray.len_shape(shape) != len(self.darray):
141            raise NdarrayError("shape is not consistent with the ndarray length")
142        self.shape = list(shape)
143
144    def update(self, nda, nda_uri=True):
145        """update uri and darray and return the result (True, False)
146
147        *Parameters*
148
149        - **nda** : string, list, np.ndarray, Ndarray - data to include
150        - **nda_uri** : boolean (default True) - if True, existing shape and
151        ntv_type are not updated (but are created if not existing)"""
152        if (
153            not nda_uri
154            and not (self.shape is None or nda.shape is None)
155            and self.shape != nda.shape
156        ):
157            return False
158        if (
159            not nda_uri
160            and not (self.ntv_type is None or nda.ntv_type is None)
161            and self.ntv_type != nda.ntv_type
162        ):
163            return False
164        if nda_uri:
165            len_s = self.len_shape(self.shape)
166            if len_s and len(nda) and len_s != len(nda):
167                return False
168            self.ntvtype = nda.ntvtype if self.ntv_type is None else self.ntvtype
169            self.shape = nda.shape if self.shape is None else self.shape
170        else:
171            self.ntvtype = nda.ntvtype if nda.ntv_type is not None else self.ntvtype
172            self.shape = nda.shape if nda.shape is not None else self.shape
173        self.uri, self.darray = (nda.uri, None) if nda.uri else (None, nda.darray)
174        return True
175
176    def set_array(self, darray):
177        """set a new darray and remove uri, return the result (True, False)
178
179        *Parameters*
180
181        - **darray** : list, np.ndarray, Ndarray - data to include"""
182        ndarray = Ndarray(darray)
183        darray = ndarray.darray
184        ntv_type = ndarray.ntv_type
185        shape = ndarray.shape
186        new_shape = shape if self.shape is None else self.shape
187        new_ntv_type = ntv_type if self.ntv_type is None else self.ntv_type
188        if (
189            len(darray) != Ndarray.len_shape(new_shape)
190            or new_ntv_type != ntv_type
191            or new_shape != shape
192        ):
193            return False
194        self.uri = None
195        self.darray = darray
196        self.ntvtype = Ndtype(new_ntv_type)
197        self.shape = new_shape
198        return True
199
200    def set_uri(self, uri, no_ntv_type=False, no_shape=False):
201        """set a new uri and remove ndarray and optionaly ntv_type and shape.
202        Return the result (True, False)
203
204        *Parameters*
205
206        - **uri** : string - URI of the Ndarray
207        - **no_ntv_type** : boolean (default False) - If True, ntv_type is None
208        - **no_shape** : boolean (default False) - If True, shape is None
209        """
210        if not isinstance(uri, str) or not uri:
211            return False
212        self.uri = uri
213        self.darray = None
214        self.ntvtype = None if no_ntv_type else self.ntvtype
215        self.shape = None if no_shape else self.shape
216        return True
217
218    def to_ndarray(self):
219        """representation with a np.ndarray not flattened"""
220        return self.ndarray
221
222    @property
223    def mode(self):
224        """representation mode of the darray/uri data (relative, absolute,
225        undefined, inconsistent)"""
226        match [self.darray, self.uri]:
227            case [None, str()]:
228                return "relative"
229            case [None, None]:
230                return "undefined"
231            case [_, None]:
232                return "absolute"
233            case _:
234                return "inconsistent"
235
236    @staticmethod
237    def read_json(jsn, **kwargs):
238        """convert json ntv_value into a ndarray.
239
240        *Parameters*
241
242        - **convert** : boolean (default True) - If True, convert json data with
243        non Numpy ntv_type into data with python type
244        """
245        option = {"convert": True} | kwargs
246        jso = json.loads(jsn) if isinstance(jsn, str) else jsn
247        (ntv_value,) = Ntv.decode_json(jso)[:1]
248
249        ntv_type = None
250        shape = None
251        match ntv_value[:-1]:
252            case []:
253                ...
254            case [ntv_type, shape]:
255                ...
256            case [str(ntv_type)]:
257                ...
258            case [list(shape)]:
259                ...
260        unidim = shape is not None
261        if isinstance(ntv_value[-1], str):
262            return Ndarray(ntv_value[-1], shape=shape, ntv_type=ntv_type)
263        darray = Darray.read_json(
264            ntv_value[-1], dtype=Nutil.dtype(ntv_type), unidim=unidim
265        )
266        darray.data = Nutil.convert(
267            ntv_type, darray.data, tojson=False, convert=option["convert"]
268        )
269        return Ndarray(darray.values, shape=shape, ntv_type=ntv_type)
270
271    def to_json(self, **kwargs):
272        """convert a Ndarray into json-value
273
274        *Parameters*
275
276        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
277        - **notype** : Boolean (default False) - including data type if False
278        - **novalue** : Boolean (default False) - including value if False
279        - **format** : string (default 'full') - representation format of the ndarray,
280        - **encoded** : Boolean (default False) - json-value if False else json-text
281        - **header** : Boolean (default True) - including ndarray type
282        """
283        option = {
284            "format": "full",
285            "header": True,
286            "encoded": False,
287            "notype": False,
288            "noshape": True,
289            "novalue": False,
290        } | kwargs
291        if self.mode in ["undefined", "inconsistent"]:
292            return None
293        if self.mode == "absolute" and len(self.darray) == 0:
294            return [[]]
295
296        shape = (
297            None
298            if not self.shape or (len(self.shape) < 2 and option["noshape"])
299            else self.shape
300        )
301
302        if self.mode == "relative":
303            js_val = self.uri
304        else:
305            js_val = (
306                Nutil.ntv_val(
307                    self.ntv_type, self.darray, option["format"], self.is_json
308                )
309                if not option["novalue"]
310                else ["-"]
311            )
312
313        lis = [self.ntv_type if not option["notype"] else None, shape, js_val]
314        return Nutil.json_ntv(
315            None,
316            "ndarray",
317            [val for val in lis if val is not None],
318            header=option["header"],
319            encoded=option["encoded"],
320        )
321
322    @property
323    def info(self):
324        """infos of the Ndarray"""
325        inf = {"shape": self.shape}
326        inf["length"] = len(self)
327        inf["ntvtype"] = self.ntv_type
328        inf["shape"] = self.shape
329        inf["uri"] = self.uri
330        return {key: val for key, val in inf.items() if val}
331
332    @staticmethod
333    def len_shape(shape):
334        """return a length from a shape (product of dimensions)"""
335        if not shape:
336            return 0
337        prod = 1
338        for dim in shape:
339            prod *= dim
340        return prod

The Ndarray class is the JSON interface of numpy.ndarrays.

static methods

Ndarray(dar, ntv_type=None, shape=None, str_uri=True)
38    def __init__(self, dar, ntv_type=None, shape=None, str_uri=True):
39        """Ndarray constructor.
40
41        *Parameters*
42
43        - **dar**: Darray or np.ndarray - data to represent
44        - **shape** : list of integer (default None) - length of dimensions
45        - **ntv_type**: string (default None) - NTVtype to apply
46        - **str_uri**: boolean(default True) - if True and dar is a string,
47        dar is an uri else a np.array
48        """
49        dar = [None] if isinstance(dar, list) and len(dar) == 0 else dar
50        if isinstance(dar, Ndarray):
51            self.uri = dar.uri
52            self.is_json = dar.is_json
53            self.ntvtype = dar.ntvtype
54            self.shape = dar.shape
55            self.darray = dar.darray
56            return
57        if isinstance(dar, str) and str_uri:
58            self.uri = dar
59            self.is_json = True
60            self.ntvtype = Ndtype(ntv_type) if ntv_type else None
61            self.shape = shape
62            self.darray = None
63            return
64        if shape:
65            dar = Dfull(dar, dtype=Nutil.dtype(ntv_type), unidim=True).data
66        else:
67            dar = np.array(dar, dtype=Nutil.dtype(ntv_type))
68            shape = list(dar.shape)
69        dar = np.array(dar).reshape(-1)
70        ntv_type = Nutil.nda_ntv_type(dar, ntv_type)
71        self.uri = None
72        self.is_json = Nutil.is_json(dar[0])
73        self.ntvtype = Ndtype(ntv_type)
74        self.shape = shape
75        self.darray = dar.astype(Nutil.dtype(str(self.ntvtype)))

Ndarray constructor.

Parameters

  • dar: Darray or np.ndarray - data to represent
  • shape : list of integer (default None) - length of dimensions
  • ntv_type: string (default None) - NTVtype to apply
  • str_uri: boolean(default True) - if True and dar is a string, dar is an uri else a np.array
uri
is_json
ntvtype
shape
darray
ntv_type
128    @property
129    def ntv_type(self):
130        """string representation of ntvtype"""
131        return str(self.ntvtype) if self.ntvtype else None

string representation of ntvtype

ndarray
133    @property
134    def ndarray(self):
135        """representation with a np.ndarray not flattened"""
136        return self.darray.reshape(self.shape) if self.darray is not None else None

representation with a np.ndarray not flattened

def set_shape(self, shape):
138    def set_shape(self, shape):
139        """update the shape"""
140        if Ndarray.len_shape(shape) != len(self.darray):
141            raise NdarrayError("shape is not consistent with the ndarray length")
142        self.shape = list(shape)

update the shape

def update(self, nda, nda_uri=True):
144    def update(self, nda, nda_uri=True):
145        """update uri and darray and return the result (True, False)
146
147        *Parameters*
148
149        - **nda** : string, list, np.ndarray, Ndarray - data to include
150        - **nda_uri** : boolean (default True) - if True, existing shape and
151        ntv_type are not updated (but are created if not existing)"""
152        if (
153            not nda_uri
154            and not (self.shape is None or nda.shape is None)
155            and self.shape != nda.shape
156        ):
157            return False
158        if (
159            not nda_uri
160            and not (self.ntv_type is None or nda.ntv_type is None)
161            and self.ntv_type != nda.ntv_type
162        ):
163            return False
164        if nda_uri:
165            len_s = self.len_shape(self.shape)
166            if len_s and len(nda) and len_s != len(nda):
167                return False
168            self.ntvtype = nda.ntvtype if self.ntv_type is None else self.ntvtype
169            self.shape = nda.shape if self.shape is None else self.shape
170        else:
171            self.ntvtype = nda.ntvtype if nda.ntv_type is not None else self.ntvtype
172            self.shape = nda.shape if nda.shape is not None else self.shape
173        self.uri, self.darray = (nda.uri, None) if nda.uri else (None, nda.darray)
174        return True

update uri and darray and return the result (True, False)

Parameters

  • nda : string, list, np.ndarray, Ndarray - data to include
  • nda_uri : boolean (default True) - if True, existing shape and ntv_type are not updated (but are created if not existing)
def set_array(self, darray):
176    def set_array(self, darray):
177        """set a new darray and remove uri, return the result (True, False)
178
179        *Parameters*
180
181        - **darray** : list, np.ndarray, Ndarray - data to include"""
182        ndarray = Ndarray(darray)
183        darray = ndarray.darray
184        ntv_type = ndarray.ntv_type
185        shape = ndarray.shape
186        new_shape = shape if self.shape is None else self.shape
187        new_ntv_type = ntv_type if self.ntv_type is None else self.ntv_type
188        if (
189            len(darray) != Ndarray.len_shape(new_shape)
190            or new_ntv_type != ntv_type
191            or new_shape != shape
192        ):
193            return False
194        self.uri = None
195        self.darray = darray
196        self.ntvtype = Ndtype(new_ntv_type)
197        self.shape = new_shape
198        return True

set a new darray and remove uri, return the result (True, False)

Parameters

  • darray : list, np.ndarray, Ndarray - data to include
def set_uri(self, uri, no_ntv_type=False, no_shape=False):
200    def set_uri(self, uri, no_ntv_type=False, no_shape=False):
201        """set a new uri and remove ndarray and optionaly ntv_type and shape.
202        Return the result (True, False)
203
204        *Parameters*
205
206        - **uri** : string - URI of the Ndarray
207        - **no_ntv_type** : boolean (default False) - If True, ntv_type is None
208        - **no_shape** : boolean (default False) - If True, shape is None
209        """
210        if not isinstance(uri, str) or not uri:
211            return False
212        self.uri = uri
213        self.darray = None
214        self.ntvtype = None if no_ntv_type else self.ntvtype
215        self.shape = None if no_shape else self.shape
216        return True

set a new uri and remove ndarray and optionaly ntv_type and shape. Return the result (True, False)

Parameters

  • uri : string - URI of the Ndarray
  • no_ntv_type : boolean (default False) - If True, ntv_type is None
  • no_shape : boolean (default False) - If True, shape is None
def to_ndarray(self):
218    def to_ndarray(self):
219        """representation with a np.ndarray not flattened"""
220        return self.ndarray

representation with a np.ndarray not flattened

mode
222    @property
223    def mode(self):
224        """representation mode of the darray/uri data (relative, absolute,
225        undefined, inconsistent)"""
226        match [self.darray, self.uri]:
227            case [None, str()]:
228                return "relative"
229            case [None, None]:
230                return "undefined"
231            case [_, None]:
232                return "absolute"
233            case _:
234                return "inconsistent"

representation mode of the darray/uri data (relative, absolute, undefined, inconsistent)

@staticmethod
def read_json(jsn, **kwargs):
236    @staticmethod
237    def read_json(jsn, **kwargs):
238        """convert json ntv_value into a ndarray.
239
240        *Parameters*
241
242        - **convert** : boolean (default True) - If True, convert json data with
243        non Numpy ntv_type into data with python type
244        """
245        option = {"convert": True} | kwargs
246        jso = json.loads(jsn) if isinstance(jsn, str) else jsn
247        (ntv_value,) = Ntv.decode_json(jso)[:1]
248
249        ntv_type = None
250        shape = None
251        match ntv_value[:-1]:
252            case []:
253                ...
254            case [ntv_type, shape]:
255                ...
256            case [str(ntv_type)]:
257                ...
258            case [list(shape)]:
259                ...
260        unidim = shape is not None
261        if isinstance(ntv_value[-1], str):
262            return Ndarray(ntv_value[-1], shape=shape, ntv_type=ntv_type)
263        darray = Darray.read_json(
264            ntv_value[-1], dtype=Nutil.dtype(ntv_type), unidim=unidim
265        )
266        darray.data = Nutil.convert(
267            ntv_type, darray.data, tojson=False, convert=option["convert"]
268        )
269        return Ndarray(darray.values, shape=shape, ntv_type=ntv_type)

convert json ntv_value into a ndarray.

Parameters

  • convert : boolean (default True) - If True, convert json data with non Numpy ntv_type into data with python type
def to_json(self, **kwargs):
271    def to_json(self, **kwargs):
272        """convert a Ndarray into json-value
273
274        *Parameters*
275
276        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
277        - **notype** : Boolean (default False) - including data type if False
278        - **novalue** : Boolean (default False) - including value if False
279        - **format** : string (default 'full') - representation format of the ndarray,
280        - **encoded** : Boolean (default False) - json-value if False else json-text
281        - **header** : Boolean (default True) - including ndarray type
282        """
283        option = {
284            "format": "full",
285            "header": True,
286            "encoded": False,
287            "notype": False,
288            "noshape": True,
289            "novalue": False,
290        } | kwargs
291        if self.mode in ["undefined", "inconsistent"]:
292            return None
293        if self.mode == "absolute" and len(self.darray) == 0:
294            return [[]]
295
296        shape = (
297            None
298            if not self.shape or (len(self.shape) < 2 and option["noshape"])
299            else self.shape
300        )
301
302        if self.mode == "relative":
303            js_val = self.uri
304        else:
305            js_val = (
306                Nutil.ntv_val(
307                    self.ntv_type, self.darray, option["format"], self.is_json
308                )
309                if not option["novalue"]
310                else ["-"]
311            )
312
313        lis = [self.ntv_type if not option["notype"] else None, shape, js_val]
314        return Nutil.json_ntv(
315            None,
316            "ndarray",
317            [val for val in lis if val is not None],
318            header=option["header"],
319            encoded=option["encoded"],
320        )

convert a Ndarray into json-value

Parameters

  • noshape : Boolean (default True) - if True, without shape if dim < 1
  • notype : Boolean (default False) - including data type if False
  • novalue : Boolean (default False) - including value if False
  • format : string (default 'full') - representation format of the ndarray,
  • encoded : Boolean (default False) - json-value if False else json-text
  • header : Boolean (default True) - including ndarray type
info
322    @property
323    def info(self):
324        """infos of the Ndarray"""
325        inf = {"shape": self.shape}
326        inf["length"] = len(self)
327        inf["ntvtype"] = self.ntv_type
328        inf["shape"] = self.shape
329        inf["uri"] = self.uri
330        return {key: val for key, val in inf.items() if val}

infos of the Ndarray

@staticmethod
def len_shape(shape):
332    @staticmethod
333    def len_shape(shape):
334        """return a length from a shape (product of dimensions)"""
335        if not shape:
336            return 0
337        prod = 1
338        for dim in shape:
339            prod *= dim
340        return prod

return a length from a shape (product of dimensions)

class Nutil:
343class Nutil:
344    """ntv-ndarray utilities.
345
346    *static methods*
347    - `convert`
348    - `is_json`
349    - `ntv_val`
350    - `add_ext`
351    - `split_type`
352    - `ntv_type`
353    - `nda_ntv_type`
354    - `dtype`
355    - `json_ntv`
356    - `split_name`
357    - `split_json_name`
358
359    """
360
361    CONNECTOR_DT = {"field": "Series", "tab": "DataFrame"}
362    PYTHON_DT = {
363        "array": "list",
364        "time": "datetime.time",
365        "object": "dict",
366        "null": "NoneType",
367        "decimal64": "Decimal",
368        "ndarray": "ndarray",
369        "narray": "narray",
370    }
371    LOCATION_DT = {"point": "Point", "line": "LineString", "polygon": "Polygon"}
372    DT_CONNECTOR = {val: key for key, val in CONNECTOR_DT.items()}
373    DT_PYTHON = {val: key for key, val in PYTHON_DT.items()}
374    DT_LOCATION = {val: key for key, val in LOCATION_DT.items()}
375    DT_NTVTYPE = DT_LOCATION | DT_CONNECTOR | DT_PYTHON
376
377    FORMAT_CLS = {"full": Dfull, "complete": Dcomplete}
378    STRUCT_DT = {"Ntv": "object", "NtvSingle": "object", "NtvList": "object"}
379    CONVERT_DT = {
380        "object": "object",
381        "array": "object",
382        "json": "object",
383        "number": "float",
384        "boolean": "bool",
385        "null": "object",
386        "string": "str",
387        "integer": "int",
388    }
389
390    @staticmethod
391    def is_json(obj):
392        """check if obj is a json structure and return True if obj is a json-value
393
394        *Parameters*
395
396        - **obj** : object to check"""
397        if obj is None:
398            return True
399        is_js = NtvConnector.is_json
400        match obj:
401            case str() | int() | float() | bool():
402                return True
403            case list() | tuple() as obj:
404                if not obj:
405                    return True
406                return min(is_js(obj_in) for obj_in in obj)
407            case dict() as obj:
408                if not obj:
409                    return True
410                if not min(isinstance(key, str) for key in obj.keys()):
411                    return False
412                return min(is_js(obj_in) for obj_in in obj.values())
413            case _:
414                return False
415
416    @staticmethod
417    def extend_array(arr, til, shap, order):
418        """return a flattened np.ndarray extended in additional dimensions
419
420        parameters:
421
422        - arr: np.array to extend
423        - til: integer - parameter to apply to np.tile function
424        - shap: list of integer - shape of the array
425        - order: list of integer - order of dimensions to apply
426        """
427        old_order = list(range(len(order)))
428        arr_tab = np.tile(arr, til).reshape(shap)
429        return np.moveaxis(arr_tab, old_order, order).flatten()
430
431    @staticmethod
432    def convert(ntv_type, nda, tojson=True, convert=True):
433        """convert np.ndarray with external NTVtype.
434
435        *Parameters*
436
437        - **ntv_type** : string - NTVtype deduced from the np.ndarray name_type and dtype,
438        - **nda** : np.ndarray to be converted.
439        - **tojson** : boolean (default True) - apply to json function
440        - **convert** : boolean (default True) - If True, convert json data with
441        non Numpy ntv_type into data with python type
442        """
443
444        dtype = Nutil.dtype(ntv_type)
445        jtype = Nutil.dtype(ntv_type, convert=False)
446        if tojson:
447            match ntv_type:
448                case dat if Ndtype(dat).category == "datation":
449                    return nda.astype(dtype).astype(jtype)
450                case "base16":
451                    return nda.astype(dtype)
452                case "time" | "decimal64":
453                    return nda.astype(jtype)
454                case "geojson":
455                    return np.frompyfunc(ShapelyConnec.to_geojson, 1, 1)(nda)
456                case _:
457                    return nda
458        else:
459            match [ntv_type, convert]:
460                case [None, _]:
461                    return nda
462                case [_, False]:
463                    return nda.astype(jtype)
464                case ["time", _]:
465                    return np.frompyfunc(datetime.time.fromisoformat, 1, 1)(nda)
466                case ["decimal64", _]:
467                    return np.frompyfunc(Decimal, 1, 1)(nda)
468                case ["narray", _]:
469                    nar = np.frompyfunc(Ndarray.read_json, 1, 1)(nda)
470                    return np.frompyfunc(Ndarray.to_ndarray, 1, 1)(nar)
471                case ["ndarray", _]:
472                    return np.frompyfunc(Ndarray.read_json, 1, 1)(nda)
473                case [("point" | "line" | "polygon" | "geometry"), _]:
474                    return np.frompyfunc(ShapelyConnec.to_geometry, 1, 1)(nda)
475                case [connec, _] if connec in Nutil.CONNECTOR_DT:
476                    return np.fromiter(
477                        [NtvConnector.uncast(nd, None, connec)[0] for nd in nda],
478                        dtype="object",
479                    )
480                case _:
481                    return nda.astype(dtype)
482
483        # float.fromhex(x.hex()) == x, bytes(bytearray.fromhex(x.hex())) == x
484
485    @staticmethod
486    def ntv_val(ntv_type, nda, form, is_json=False):
487        """convert a np.ndarray into NTV json-value.
488
489        *Parameters*
490
491        - **ntv_type** : string - NTVtype deduced from the ndarray, name_type and dtype,
492        - **nda** : ndarray to be converted.
493        - **form** : format of data ('full', 'complete', 'sparse', 'primary').
494        - **is_json** : boolean (defaut False) - True if nda data is Json data
495        """
496        if form == "complete" and len(nda) < 2:
497            raise NdarrayError(
498                "complete format is not available with ndarray length < 2"
499            )
500        Format = Nutil.FORMAT_CLS[form]
501        darray = Format(nda)
502        ref = darray.ref
503        coding = darray.coding
504        if is_json:
505            return Format(darray.data, ref=ref, coding=coding).to_json()
506        match ntv_type:
507            case "narray":
508                data = [Ndarray(nd).to_json(header=False) for nd in darray.data]
509            case "ndarray":
510                data = [Ndarray(nd).to_json(header=False) for nd in darray.data]
511            case connec if connec in Nutil.CONNECTOR_DT:
512                data = [NtvConnector.cast(nd, None, connec)[0] for nd in darray.data]
513            case "point" | "line" | "polygon" | "geometry":
514                data = np.frompyfunc(ShapelyConnec.to_coord, 1, 1)(darray.data)
515            case None:
516                data = nda
517            case _:
518                data = Nutil.convert(ntv_type, darray.data)
519        return Format(data, ref=ref, coding=coding).to_json()
520
521    @staticmethod
522    def add_ext(typ, ext):
523        '''return extended type string: "typ[ext]"'''
524        ext = "[" + ext + "]" if ext else ""
525        return "" if not typ else typ + ext
526
527    @staticmethod
528    def split_type(typ):
529        """return a tuple with typ and extension"""
530        if not isinstance(typ, str):
531            return (None, None)
532        spl = typ.split("[", maxsplit=1)
533        return (spl[0], None) if len(spl) == 1 else (spl[0], spl[1][:-1])
534
535    @staticmethod
536    def split_json_name(string, notnone=False):
537        """return a tuple with name, ntv_type from string"""
538        null = "" if notnone else None
539        if not string or string == ":":
540            return (null, null)
541        spl = string.rsplit(":", maxsplit=1)
542        if len(spl) == 1:
543            return (string, null)
544        if spl[0] == "":
545            return (null, spl[1])
546        sp0 = spl[0][:-1] if spl[0][-1] == ":" else spl[0]
547        return (null if sp0 == "" else sp0, null if spl[1] == "" else spl[1])
548
549    @staticmethod
550    def split_name(string):
551        """return a list with name, add_name from string"""
552        if not string or string == ".":
553            return ["", ""]
554        spl = string.split(".", maxsplit=1)
555        spl = [spl[0], ""] if len(spl) < 2 else spl
556        return spl
557
558    @staticmethod
559    def ntv_type(dtype, ntv_type=None, ext=None):
560        """return ntv_type string from dtype, additional type and extension.
561
562        *Parameters*
563
564        - **dtype** : string - dtype of the ndarray
565        - **ntv_type** : string - additional type
566        - **ext** : string - type extension
567        """
568        np_ntype = NP_NTYPE | Nutil.DT_NTVTYPE | {"int": "int", "object": "object"}
569        if ntv_type:
570            return Nutil.add_ext(ntv_type, ext)
571        match dtype:
572            case string if string[:3] == "str":
573                return Nutil.add_ext("string", ext)
574            case bytesxx if bytesxx[:5] == "bytes":
575                return Nutil.add_ext("base16", ext)
576            case dtyp if dtyp in np_ntype:
577                return Nutil.add_ext(np_ntype[dtyp], ext)
578            case date if date[:10] == "datetime64":
579                return "datetime" + date[10:]
580            case delta if delta[:11] == "timedelta64":
581                return "timedelta" + delta[11:]
582            case _:
583                return Nutil.add_ext(dtype, ext)
584
585    @staticmethod
586    def nda_ntv_type(nda, ntv_type=None, ext=None):
587        """return ntv_type string from an ndarray, additional type and extension.
588
589        *Parameters*
590
591        - **nda** : ndarray - data used to calculate the ntv_type
592        - **ntv_type** : string - additional type
593        - **ext** : string - type extension
594        """
595        if ntv_type or nda is None:
596            return ntv_type
597        dtype = nda.dtype.name
598        pytype = nda.flat[0].__class__.__name__
599        dtype = pytype if dtype == "object" and pytype not in Nutil.STRUCT_DT else dtype
600        return Nutil.ntv_type(dtype, ntv_type, ext)
601
602    @staticmethod
603    def dtype(ntv_type, convert=True):
604        """return dtype from ntv_type
605
606        *parameters*
607
608        - **convert** : boolean (default True) - if True, dtype if from converted data
609        """
610        if not ntv_type:
611            return None
612        if convert:
613            if ntv_type[:8] == "datetime" and ntv_type[8:]:
614                return "datetime64" + ntv_type[8:]
615            return Ndtype(ntv_type).dtype
616        return Nutil.CONVERT_DT[Ndtype(ntv_type).json_type]
617
618    @staticmethod
619    def json_ntv(ntv_name, ntv_type, ntv_value, **kwargs):
620        """return the JSON representation of a NTV entity
621
622        *parameters*
623
624        - **ntv_name** : string - name of the NTV
625        - **ntv_type** : string - type of the NTV
626        - **ntv_value** : string - Json value of the NTV
627        - **encoded** : boolean (default False) - if True return JsonText else JsonValue
628        - **header** : boolean (default True) - if True include ntv_name + ntv_type
629        """
630        name = ntv_name if ntv_name else ""
631        option = {"encoded": False, "header": True} | kwargs
632        if option["header"] or name:
633            typ = ":" + ntv_type if option["header"] and ntv_type else ""
634            jsn = {name + typ: ntv_value} if name + typ else ntv_value
635        else:
636            jsn = ntv_value
637        if option["encoded"]:
638            return json.dumps(jsn)
639        return jsn
CONNECTOR_DT = {'field': 'Series', 'tab': 'DataFrame'}
PYTHON_DT = {'array': 'list', 'time': 'datetime.time', 'object': 'dict', 'null': 'NoneType', 'decimal64': 'Decimal', 'ndarray': 'ndarray', 'narray': 'narray'}
LOCATION_DT = {'point': 'Point', 'line': 'LineString', 'polygon': 'Polygon'}
DT_CONNECTOR = {'Series': 'field', 'DataFrame': 'tab'}
DT_PYTHON = {'list': 'array', 'datetime.time': 'time', 'dict': 'object', 'NoneType': 'null', 'Decimal': 'decimal64', 'ndarray': 'ndarray', 'narray': 'narray'}
DT_LOCATION = {'Point': 'point', 'LineString': 'line', 'Polygon': 'polygon'}
DT_NTVTYPE = {'Point': 'point', 'LineString': 'line', 'Polygon': 'polygon', 'Series': 'field', 'DataFrame': 'tab', 'list': 'array', 'datetime.time': 'time', 'dict': 'object', 'NoneType': 'null', 'Decimal': 'decimal64', 'ndarray': 'ndarray', 'narray': 'narray'}
FORMAT_CLS = {'full': <class 'Dfull'>, 'complete': <class 'Dcomplete'>}
STRUCT_DT = {'Ntv': 'object', 'NtvSingle': 'object', 'NtvList': 'object'}
CONVERT_DT = {'object': 'object', 'array': 'object', 'json': 'object', 'number': 'float', 'boolean': 'bool', 'null': 'object', 'string': 'str', 'integer': 'int'}
@staticmethod
def is_json(obj):
390    @staticmethod
391    def is_json(obj):
392        """check if obj is a json structure and return True if obj is a json-value
393
394        *Parameters*
395
396        - **obj** : object to check"""
397        if obj is None:
398            return True
399        is_js = NtvConnector.is_json
400        match obj:
401            case str() | int() | float() | bool():
402                return True
403            case list() | tuple() as obj:
404                if not obj:
405                    return True
406                return min(is_js(obj_in) for obj_in in obj)
407            case dict() as obj:
408                if not obj:
409                    return True
410                if not min(isinstance(key, str) for key in obj.keys()):
411                    return False
412                return min(is_js(obj_in) for obj_in in obj.values())
413            case _:
414                return False

check if obj is a json structure and return True if obj is a json-value

Parameters

  • obj : object to check
@staticmethod
def extend_array(arr, til, shap, order):
416    @staticmethod
417    def extend_array(arr, til, shap, order):
418        """return a flattened np.ndarray extended in additional dimensions
419
420        parameters:
421
422        - arr: np.array to extend
423        - til: integer - parameter to apply to np.tile function
424        - shap: list of integer - shape of the array
425        - order: list of integer - order of dimensions to apply
426        """
427        old_order = list(range(len(order)))
428        arr_tab = np.tile(arr, til).reshape(shap)
429        return np.moveaxis(arr_tab, old_order, order).flatten()

return a flattened np.ndarray extended in additional dimensions

parameters:

  • arr: np.array to extend
  • til: integer - parameter to apply to np.tile function
  • shap: list of integer - shape of the array
  • order: list of integer - order of dimensions to apply
@staticmethod
def convert(ntv_type, nda, tojson=True, convert=True):
431    @staticmethod
432    def convert(ntv_type, nda, tojson=True, convert=True):
433        """convert np.ndarray with external NTVtype.
434
435        *Parameters*
436
437        - **ntv_type** : string - NTVtype deduced from the np.ndarray name_type and dtype,
438        - **nda** : np.ndarray to be converted.
439        - **tojson** : boolean (default True) - apply to json function
440        - **convert** : boolean (default True) - If True, convert json data with
441        non Numpy ntv_type into data with python type
442        """
443
444        dtype = Nutil.dtype(ntv_type)
445        jtype = Nutil.dtype(ntv_type, convert=False)
446        if tojson:
447            match ntv_type:
448                case dat if Ndtype(dat).category == "datation":
449                    return nda.astype(dtype).astype(jtype)
450                case "base16":
451                    return nda.astype(dtype)
452                case "time" | "decimal64":
453                    return nda.astype(jtype)
454                case "geojson":
455                    return np.frompyfunc(ShapelyConnec.to_geojson, 1, 1)(nda)
456                case _:
457                    return nda
458        else:
459            match [ntv_type, convert]:
460                case [None, _]:
461                    return nda
462                case [_, False]:
463                    return nda.astype(jtype)
464                case ["time", _]:
465                    return np.frompyfunc(datetime.time.fromisoformat, 1, 1)(nda)
466                case ["decimal64", _]:
467                    return np.frompyfunc(Decimal, 1, 1)(nda)
468                case ["narray", _]:
469                    nar = np.frompyfunc(Ndarray.read_json, 1, 1)(nda)
470                    return np.frompyfunc(Ndarray.to_ndarray, 1, 1)(nar)
471                case ["ndarray", _]:
472                    return np.frompyfunc(Ndarray.read_json, 1, 1)(nda)
473                case [("point" | "line" | "polygon" | "geometry"), _]:
474                    return np.frompyfunc(ShapelyConnec.to_geometry, 1, 1)(nda)
475                case [connec, _] if connec in Nutil.CONNECTOR_DT:
476                    return np.fromiter(
477                        [NtvConnector.uncast(nd, None, connec)[0] for nd in nda],
478                        dtype="object",
479                    )
480                case _:
481                    return nda.astype(dtype)
482
483        # float.fromhex(x.hex()) == x, bytes(bytearray.fromhex(x.hex())) == x

convert np.ndarray with external NTVtype.

Parameters

  • ntv_type : string - NTVtype deduced from the np.ndarray name_type and dtype,
  • nda : np.ndarray to be converted.
  • tojson : boolean (default True) - apply to json function
  • convert : boolean (default True) - If True, convert json data with non Numpy ntv_type into data with python type
@staticmethod
def ntv_val(ntv_type, nda, form, is_json=False):
485    @staticmethod
486    def ntv_val(ntv_type, nda, form, is_json=False):
487        """convert a np.ndarray into NTV json-value.
488
489        *Parameters*
490
491        - **ntv_type** : string - NTVtype deduced from the ndarray, name_type and dtype,
492        - **nda** : ndarray to be converted.
493        - **form** : format of data ('full', 'complete', 'sparse', 'primary').
494        - **is_json** : boolean (defaut False) - True if nda data is Json data
495        """
496        if form == "complete" and len(nda) < 2:
497            raise NdarrayError(
498                "complete format is not available with ndarray length < 2"
499            )
500        Format = Nutil.FORMAT_CLS[form]
501        darray = Format(nda)
502        ref = darray.ref
503        coding = darray.coding
504        if is_json:
505            return Format(darray.data, ref=ref, coding=coding).to_json()
506        match ntv_type:
507            case "narray":
508                data = [Ndarray(nd).to_json(header=False) for nd in darray.data]
509            case "ndarray":
510                data = [Ndarray(nd).to_json(header=False) for nd in darray.data]
511            case connec if connec in Nutil.CONNECTOR_DT:
512                data = [NtvConnector.cast(nd, None, connec)[0] for nd in darray.data]
513            case "point" | "line" | "polygon" | "geometry":
514                data = np.frompyfunc(ShapelyConnec.to_coord, 1, 1)(darray.data)
515            case None:
516                data = nda
517            case _:
518                data = Nutil.convert(ntv_type, darray.data)
519        return Format(data, ref=ref, coding=coding).to_json()

convert a np.ndarray into NTV json-value.

Parameters

  • ntv_type : string - NTVtype deduced from the ndarray, name_type and dtype,
  • nda : ndarray to be converted.
  • form : format of data ('full', 'complete', 'sparse', 'primary').
  • is_json : boolean (defaut False) - True if nda data is Json data
@staticmethod
def add_ext(typ, ext):
521    @staticmethod
522    def add_ext(typ, ext):
523        '''return extended type string: "typ[ext]"'''
524        ext = "[" + ext + "]" if ext else ""
525        return "" if not typ else typ + ext

return extended type string: "typ[ext]"

@staticmethod
def split_type(typ):
527    @staticmethod
528    def split_type(typ):
529        """return a tuple with typ and extension"""
530        if not isinstance(typ, str):
531            return (None, None)
532        spl = typ.split("[", maxsplit=1)
533        return (spl[0], None) if len(spl) == 1 else (spl[0], spl[1][:-1])

return a tuple with typ and extension

@staticmethod
def split_json_name(string, notnone=False):
535    @staticmethod
536    def split_json_name(string, notnone=False):
537        """return a tuple with name, ntv_type from string"""
538        null = "" if notnone else None
539        if not string or string == ":":
540            return (null, null)
541        spl = string.rsplit(":", maxsplit=1)
542        if len(spl) == 1:
543            return (string, null)
544        if spl[0] == "":
545            return (null, spl[1])
546        sp0 = spl[0][:-1] if spl[0][-1] == ":" else spl[0]
547        return (null if sp0 == "" else sp0, null if spl[1] == "" else spl[1])

return a tuple with name, ntv_type from string

@staticmethod
def split_name(string):
549    @staticmethod
550    def split_name(string):
551        """return a list with name, add_name from string"""
552        if not string or string == ".":
553            return ["", ""]
554        spl = string.split(".", maxsplit=1)
555        spl = [spl[0], ""] if len(spl) < 2 else spl
556        return spl

return a list with name, add_name from string

@staticmethod
def ntv_type(dtype, ntv_type=None, ext=None):
558    @staticmethod
559    def ntv_type(dtype, ntv_type=None, ext=None):
560        """return ntv_type string from dtype, additional type and extension.
561
562        *Parameters*
563
564        - **dtype** : string - dtype of the ndarray
565        - **ntv_type** : string - additional type
566        - **ext** : string - type extension
567        """
568        np_ntype = NP_NTYPE | Nutil.DT_NTVTYPE | {"int": "int", "object": "object"}
569        if ntv_type:
570            return Nutil.add_ext(ntv_type, ext)
571        match dtype:
572            case string if string[:3] == "str":
573                return Nutil.add_ext("string", ext)
574            case bytesxx if bytesxx[:5] == "bytes":
575                return Nutil.add_ext("base16", ext)
576            case dtyp if dtyp in np_ntype:
577                return Nutil.add_ext(np_ntype[dtyp], ext)
578            case date if date[:10] == "datetime64":
579                return "datetime" + date[10:]
580            case delta if delta[:11] == "timedelta64":
581                return "timedelta" + delta[11:]
582            case _:
583                return Nutil.add_ext(dtype, ext)

return ntv_type string from dtype, additional type and extension.

Parameters

  • dtype : string - dtype of the ndarray
  • ntv_type : string - additional type
  • ext : string - type extension
@staticmethod
def nda_ntv_type(nda, ntv_type=None, ext=None):
585    @staticmethod
586    def nda_ntv_type(nda, ntv_type=None, ext=None):
587        """return ntv_type string from an ndarray, additional type and extension.
588
589        *Parameters*
590
591        - **nda** : ndarray - data used to calculate the ntv_type
592        - **ntv_type** : string - additional type
593        - **ext** : string - type extension
594        """
595        if ntv_type or nda is None:
596            return ntv_type
597        dtype = nda.dtype.name
598        pytype = nda.flat[0].__class__.__name__
599        dtype = pytype if dtype == "object" and pytype not in Nutil.STRUCT_DT else dtype
600        return Nutil.ntv_type(dtype, ntv_type, ext)

return ntv_type string from an ndarray, additional type and extension.

Parameters

  • nda : ndarray - data used to calculate the ntv_type
  • ntv_type : string - additional type
  • ext : string - type extension
@staticmethod
def dtype(ntv_type, convert=True):
602    @staticmethod
603    def dtype(ntv_type, convert=True):
604        """return dtype from ntv_type
605
606        *parameters*
607
608        - **convert** : boolean (default True) - if True, dtype if from converted data
609        """
610        if not ntv_type:
611            return None
612        if convert:
613            if ntv_type[:8] == "datetime" and ntv_type[8:]:
614                return "datetime64" + ntv_type[8:]
615            return Ndtype(ntv_type).dtype
616        return Nutil.CONVERT_DT[Ndtype(ntv_type).json_type]

return dtype from ntv_type

parameters

  • convert : boolean (default True) - if True, dtype if from converted data
@staticmethod
def json_ntv(ntv_name, ntv_type, ntv_value, **kwargs):
618    @staticmethod
619    def json_ntv(ntv_name, ntv_type, ntv_value, **kwargs):
620        """return the JSON representation of a NTV entity
621
622        *parameters*
623
624        - **ntv_name** : string - name of the NTV
625        - **ntv_type** : string - type of the NTV
626        - **ntv_value** : string - Json value of the NTV
627        - **encoded** : boolean (default False) - if True return JsonText else JsonValue
628        - **header** : boolean (default True) - if True include ntv_name + ntv_type
629        """
630        name = ntv_name if ntv_name else ""
631        option = {"encoded": False, "header": True} | kwargs
632        if option["header"] or name:
633            typ = ":" + ntv_type if option["header"] and ntv_type else ""
634            jsn = {name + typ: ntv_value} if name + typ else ntv_value
635        else:
636            jsn = ntv_value
637        if option["encoded"]:
638            return json.dumps(jsn)
639        return jsn

return the JSON representation of a NTV entity

parameters

  • ntv_name : string - name of the NTV
  • ntv_type : string - type of the NTV
  • ntv_value : string - Json value of the NTV
  • encoded : boolean (default False) - if True return JsonText else JsonValue
  • header : boolean (default True) - if True include ntv_name + ntv_type
class Xndarray:
 21class Xndarray:
 22    """Representation of a labelled multidimensional Array
 23
 24    *Attributes :*
 25    - **name** :  string - name of the Xndarray
 26    - **add_name** :  string - additional name of the Xndarray
 27    - **nda**: Ndarray - ndarray data
 28    - **links**: list of string - links to other Xndarray
 29    - **meta** : JsonValue - informations
 30
 31    *dynamic values (@property)*
 32    - `darray`
 33    - `ndarray`
 34    - `uri`
 35    - `shape`
 36    - `ntv_type`
 37    - `info`
 38    - `mode`
 39    - `xtype`
 40    - `full_name`
 41    - `json_name`
 42
 43    *methods*
 44    - `to_json`
 45    - `read_json (static method)`
 46    - `set_ndarray`
 47    """
 48
 49    def __init__(self, full_name, nda=None, links=None, meta=None):
 50        """Xndarray constructor.
 51
 52        *Parameters*
 53
 54        - **full_name**: string (default None) - name with additional name
 55        - **nda** : Ndarray (default None) - data
 56        - **links**: List of string (default None) - dims or other names of associated Xndarray
 57        - **ntv_type**: string (default None) - ntv_type to apply to data
 58        - **meta**: dict (default None) - information
 59        """
 60        if isinstance(full_name, Xndarray):
 61            self.name = full_name.name
 62            self.add_name = full_name.add_name
 63            self.nda = full_name.nda
 64            self.links = full_name.links
 65            self.meta = full_name.meta
 66            return
 67        self.name, self.add_name = Nutil.split_name(full_name)
 68        self.nda = Ndarray(nda) if nda is not None else None
 69        self.links = links if links else None
 70        self.meta = meta if meta else None
 71        if self.meta is None and self.nda is None:
 72            raise NdarrayError("A Xndarray has to have metadata or Ndarray")
 73
 74    def __repr__(self):
 75        """return classname and number of value"""
 76        return self.__class__.__name__ + "[" + self.full_name + "]"
 77
 78    def __str__(self):
 79        """return json string format"""
 80        return json.dumps(self.to_json())
 81
 82    def __eq__(self, other):
 83        """equal if attributes are equal"""
 84        if self.name != other.name or self.add_name != other.add_name:
 85            return False
 86        if self.links != other.links or self.meta != other.meta:
 87            return False
 88        if self.nda is None and other.nda is None:
 89            return True
 90        if self.nda is None or other.nda is None:
 91            return False
 92        return self.nda == other.nda
 93
 94    def __len__(self):
 95        """len of ndarray"""
 96        return len(self.nda) if self.nda is not None else 0
 97
 98    def __contains__(self, item):
 99        """item of ndarray values"""
100        return item in self.nda if self.nda is not None else None
101
102    def __getitem__(self, ind):
103        """return ndarray value item"""
104        if self.nda is None:
105            return None
106        if isinstance(ind, tuple):
107            return [self.nda[i] for i in ind]
108        return self.nda[ind]
109
110    def __copy__(self):
111        """Copy all the data"""
112        return self.__class__(self)
113
114    @property
115    def darray(self):
116        """return the darray of the ndarray"""
117        return self.nda.darray if self.nda is not None else None
118
119    @property
120    def ndarray(self):
121        """return the darray of the ndarray"""
122        return self.nda.ndarray if self.nda is not None else None
123
124    @property
125    def uri(self):
126        """return the uri of the ndarray"""
127        return self.nda.uri if self.nda is not None else None
128
129    @property
130    def shape(self):
131        """return the shape of the ndarray"""
132        return self.nda.shape if self.nda is not None else None
133
134    @property
135    def ntv_type(self):
136        """return the ntv_type of the ndarray"""
137        return self.nda.ntv_type if self.nda is not None else None
138
139    @property
140    def mode(self):
141        """return the mode of the ndarray"""
142        return self.nda.mode if self.nda is not None else "undefined"
143
144    @property
145    def info(self):
146        """infos of the Xndarray"""
147        inf = {"name": self.full_name}
148        inf["length"] = len(self)
149        if self.nda:
150            inf["mode"] = self.mode
151            inf["ntvtype"] = self.ntv_type
152            inf["shape"] = self.shape
153        inf["uri"] = self.uri
154        inf["meta"] = self.meta
155        inf["xtype"] = self.xtype
156        inf["links"] = self.links
157        return {key: val for key, val in inf.items() if val}
158
159    @property
160    def xtype(self):
161        """nature of the Xndarray (undefined, namedarray, variable, additional,
162        meta, inconsistent)"""
163        match [self.links, self.add_name, self.mode]:
164            case [_, _, "inconsistent"]:
165                return "inconsistent"
166            case [_, _, "undefined"]:
167                return "meta"
168            case [None, "", _]:
169                return "namedarray"
170            case [_, "", _]:
171                return "variable"
172            case [_, str(), _]:
173                return "additional"
174            case _:
175                return "inconsistent"
176
177    @property
178    def full_name(self):
179        """concatenation of name and additional name"""
180        add_name = "." + self.add_name if self.add_name else ""
181        return self.name + add_name
182
183    @property
184    def json_name(self):
185        """concatenation of full_name and ntv_type"""
186        add_ntv_type = ":" + self.ntv_type if self.ntv_type else ""
187        return self.full_name + add_ntv_type
188
189    @staticmethod
190    def read_json(jsn, **kwargs):
191        """convert json data into a Xndarray.
192
193        *Parameters*
194
195        - **convert** : boolean (default True) - If True, convert json data with
196        non Numpy ntv_type into data with python type
197        """
198        option = {"convert": True} | kwargs
199        jso = json.loads(jsn) if isinstance(jsn, str) else jsn
200        value, full_name = Ntv.decode_json(jso)[:2]
201
202        meta = links = nda = None
203        match value:
204            case str(meta) | dict(meta):
205                ...
206            case [list(nda)]:
207                ...
208            case [list(nda), list(links)]:
209                ...
210            case [list(nda), dict(meta)] | [list(nda), str(meta)]:
211                ...
212            case [list(nda), list(links), dict(meta)]:
213                ...
214            case [list(nda), list(links), str(meta)]:
215                ...
216            case _:
217                return None
218        nda = Ndarray.read_json(nda, **option) if nda else None
219        return Xndarray(full_name, links=links, meta=meta, nda=nda)
220
221    def set_ndarray(self, ndarray, nda_uri=True):
222        """set a new ndarray (nda) and return the result (True, False)
223
224        *Parameters*
225
226        - **ndarray** : string, list, np.ndarray, Ndarray - data to include
227        - **nda_uri** : boolean (default True) - if True, existing shape and
228        ntv_type are not updated (but are created if not existing)"""
229        ndarray = Ndarray(ndarray)
230        if self.nda is not None:
231            return self.nda.update(ndarray, nda_uri=nda_uri)
232        self.nda = ndarray
233        return True
234
235    def to_json(self, **kwargs):
236        """convert a Xndarray into json-value.
237
238        *Parameters*
239
240        - **encoded** : Boolean (default False) - json-value if False else json-text
241        - **header** : Boolean (default True) - including xndarray type
242        - **noname** : Boolean (default False) - including data type and name if False
243        - **notype** : Boolean (default False) - including data type if False
244        - **novalue** : Boolean (default False) - including value if False
245        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
246        - **format** : string (default 'full') - representation format of the ndarray,
247        - **extension** : string (default None) - type extension
248        """
249        option = {
250            "notype": False,
251            "format": "full",
252            "noshape": True,
253            "header": True,
254            "encoded": False,
255            "novalue": False,
256            "noname": False,
257        } | kwargs
258        if option["format"] not in ["full", "complete"]:
259            option["noshape"] = False
260        opt_nda = option | {"header": False}
261        nda_str = self.nda.to_json(**opt_nda) if self.nda is not None else None
262        lis = [nda_str, self.links, self.meta]
263        lis = [val for val in lis if val is not None]
264        return Nutil.json_ntv(
265            None if option["noname"] else self.full_name,
266            None if option["noname"] else "xndarray",
267            lis[0] if lis == [self.meta] else lis,
268            header=option["header"],
269            encoded=option["encoded"],
270        )
271
272    def _to_json(self):
273        """return dict of attributes"""
274        return {
275            "name": self.name,
276            "ntv_type": self.ntv_type,
277            "uri": self.uri,
278            "nda": self.nda,
279            "meta": self.meta,
280            "links": self.links,
281        }

Representation of a labelled multidimensional Array

Attributes :

  • name : string - name of the Xndarray
  • add_name : string - additional name of the Xndarray
  • nda: Ndarray - ndarray data
  • links: list of string - links to other Xndarray
  • meta : JsonValue - informations

dynamic values (@property)

methods

Xndarray(full_name, nda=None, links=None, meta=None)
49    def __init__(self, full_name, nda=None, links=None, meta=None):
50        """Xndarray constructor.
51
52        *Parameters*
53
54        - **full_name**: string (default None) - name with additional name
55        - **nda** : Ndarray (default None) - data
56        - **links**: List of string (default None) - dims or other names of associated Xndarray
57        - **ntv_type**: string (default None) - ntv_type to apply to data
58        - **meta**: dict (default None) - information
59        """
60        if isinstance(full_name, Xndarray):
61            self.name = full_name.name
62            self.add_name = full_name.add_name
63            self.nda = full_name.nda
64            self.links = full_name.links
65            self.meta = full_name.meta
66            return
67        self.name, self.add_name = Nutil.split_name(full_name)
68        self.nda = Ndarray(nda) if nda is not None else None
69        self.links = links if links else None
70        self.meta = meta if meta else None
71        if self.meta is None and self.nda is None:
72            raise NdarrayError("A Xndarray has to have metadata or Ndarray")

Xndarray constructor.

Parameters

  • full_name: string (default None) - name with additional name
  • nda : Ndarray (default None) - data
  • links: List of string (default None) - dims or other names of associated Xndarray
  • ntv_type: string (default None) - ntv_type to apply to data
  • meta: dict (default None) - information
nda
meta
darray
114    @property
115    def darray(self):
116        """return the darray of the ndarray"""
117        return self.nda.darray if self.nda is not None else None

return the darray of the ndarray

ndarray
119    @property
120    def ndarray(self):
121        """return the darray of the ndarray"""
122        return self.nda.ndarray if self.nda is not None else None

return the darray of the ndarray

uri
124    @property
125    def uri(self):
126        """return the uri of the ndarray"""
127        return self.nda.uri if self.nda is not None else None

return the uri of the ndarray

shape
129    @property
130    def shape(self):
131        """return the shape of the ndarray"""
132        return self.nda.shape if self.nda is not None else None

return the shape of the ndarray

ntv_type
134    @property
135    def ntv_type(self):
136        """return the ntv_type of the ndarray"""
137        return self.nda.ntv_type if self.nda is not None else None

return the ntv_type of the ndarray

mode
139    @property
140    def mode(self):
141        """return the mode of the ndarray"""
142        return self.nda.mode if self.nda is not None else "undefined"

return the mode of the ndarray

info
144    @property
145    def info(self):
146        """infos of the Xndarray"""
147        inf = {"name": self.full_name}
148        inf["length"] = len(self)
149        if self.nda:
150            inf["mode"] = self.mode
151            inf["ntvtype"] = self.ntv_type
152            inf["shape"] = self.shape
153        inf["uri"] = self.uri
154        inf["meta"] = self.meta
155        inf["xtype"] = self.xtype
156        inf["links"] = self.links
157        return {key: val for key, val in inf.items() if val}

infos of the Xndarray

xtype
159    @property
160    def xtype(self):
161        """nature of the Xndarray (undefined, namedarray, variable, additional,
162        meta, inconsistent)"""
163        match [self.links, self.add_name, self.mode]:
164            case [_, _, "inconsistent"]:
165                return "inconsistent"
166            case [_, _, "undefined"]:
167                return "meta"
168            case [None, "", _]:
169                return "namedarray"
170            case [_, "", _]:
171                return "variable"
172            case [_, str(), _]:
173                return "additional"
174            case _:
175                return "inconsistent"

nature of the Xndarray (undefined, namedarray, variable, additional, meta, inconsistent)

full_name
177    @property
178    def full_name(self):
179        """concatenation of name and additional name"""
180        add_name = "." + self.add_name if self.add_name else ""
181        return self.name + add_name

concatenation of name and additional name

json_name
183    @property
184    def json_name(self):
185        """concatenation of full_name and ntv_type"""
186        add_ntv_type = ":" + self.ntv_type if self.ntv_type else ""
187        return self.full_name + add_ntv_type

concatenation of full_name and ntv_type

@staticmethod
def read_json(jsn, **kwargs):
189    @staticmethod
190    def read_json(jsn, **kwargs):
191        """convert json data into a Xndarray.
192
193        *Parameters*
194
195        - **convert** : boolean (default True) - If True, convert json data with
196        non Numpy ntv_type into data with python type
197        """
198        option = {"convert": True} | kwargs
199        jso = json.loads(jsn) if isinstance(jsn, str) else jsn
200        value, full_name = Ntv.decode_json(jso)[:2]
201
202        meta = links = nda = None
203        match value:
204            case str(meta) | dict(meta):
205                ...
206            case [list(nda)]:
207                ...
208            case [list(nda), list(links)]:
209                ...
210            case [list(nda), dict(meta)] | [list(nda), str(meta)]:
211                ...
212            case [list(nda), list(links), dict(meta)]:
213                ...
214            case [list(nda), list(links), str(meta)]:
215                ...
216            case _:
217                return None
218        nda = Ndarray.read_json(nda, **option) if nda else None
219        return Xndarray(full_name, links=links, meta=meta, nda=nda)

convert json data into a Xndarray.

Parameters

  • convert : boolean (default True) - If True, convert json data with non Numpy ntv_type into data with python type
def set_ndarray(self, ndarray, nda_uri=True):
221    def set_ndarray(self, ndarray, nda_uri=True):
222        """set a new ndarray (nda) and return the result (True, False)
223
224        *Parameters*
225
226        - **ndarray** : string, list, np.ndarray, Ndarray - data to include
227        - **nda_uri** : boolean (default True) - if True, existing shape and
228        ntv_type are not updated (but are created if not existing)"""
229        ndarray = Ndarray(ndarray)
230        if self.nda is not None:
231            return self.nda.update(ndarray, nda_uri=nda_uri)
232        self.nda = ndarray
233        return True

set a new ndarray (nda) and return the result (True, False)

Parameters

  • ndarray : string, list, np.ndarray, Ndarray - data to include
  • nda_uri : boolean (default True) - if True, existing shape and ntv_type are not updated (but are created if not existing)
def to_json(self, **kwargs):
235    def to_json(self, **kwargs):
236        """convert a Xndarray into json-value.
237
238        *Parameters*
239
240        - **encoded** : Boolean (default False) - json-value if False else json-text
241        - **header** : Boolean (default True) - including xndarray type
242        - **noname** : Boolean (default False) - including data type and name if False
243        - **notype** : Boolean (default False) - including data type if False
244        - **novalue** : Boolean (default False) - including value if False
245        - **noshape** : Boolean (default True) - if True, without shape if dim < 1
246        - **format** : string (default 'full') - representation format of the ndarray,
247        - **extension** : string (default None) - type extension
248        """
249        option = {
250            "notype": False,
251            "format": "full",
252            "noshape": True,
253            "header": True,
254            "encoded": False,
255            "novalue": False,
256            "noname": False,
257        } | kwargs
258        if option["format"] not in ["full", "complete"]:
259            option["noshape"] = False
260        opt_nda = option | {"header": False}
261        nda_str = self.nda.to_json(**opt_nda) if self.nda is not None else None
262        lis = [nda_str, self.links, self.meta]
263        lis = [val for val in lis if val is not None]
264        return Nutil.json_ntv(
265            None if option["noname"] else self.full_name,
266            None if option["noname"] else "xndarray",
267            lis[0] if lis == [self.meta] else lis,
268            header=option["header"],
269            encoded=option["encoded"],
270        )

convert a Xndarray into json-value.

Parameters

  • encoded : Boolean (default False) - json-value if False else json-text
  • header : Boolean (default True) - including xndarray type
  • noname : Boolean (default False) - including data type and name if False
  • notype : Boolean (default False) - including data type if False
  • novalue : Boolean (default False) - including value if False
  • noshape : Boolean (default True) - if True, without shape if dim < 1
  • format : string (default 'full') - representation format of the ndarray,
  • extension : string (default None) - type extension
class Xdataset(ntv_numpy.xdataset.XdatasetCategory, ntv_numpy.xdataset.XdatasetInterface):
323class Xdataset(XdatasetCategory, XdatasetInterface):
324    """Representation of a multidimensional Dataset
325
326    *Attributes :*
327    - **name** :  String - name of the Xdataset
328    - **xnd**:   list of Xndarray
329
330    *dynamic values (@property)*
331    - `xtype`
332    - `validity`
333    - `dic_xnd`
334    - `partition`
335    - `length`
336    - `info`
337
338    *methods*
339    - `parent`
340    - `dims`
341    - `shape_dims`
342    - `to_canonical`
343    - `to_ndarray`
344    - `to_darray`
345
346    *XdatasetCategory (@property)*
347    - `names`
348    - `data_arrays`
349    - `dimensions`
350    - `coordinates`
351    - `data_vars`
352    - `namedarrays`
353    - `variables`
354    - `undef_vars`
355    - `undef_links`
356    - `masks`
357    - `data_add`
358    - `meta`
359    - `metadata`
360    - `uniques`
361    - `additionals`
362    - `group`
363    - `add_group`
364
365    *XdatasetInterface methods *
366    - `read_json` (static)
367    - `to_json`
368    - `from_xarray` (static)
369    - `to_xarray`
370    - `from_scipp` (static)
371    - `to_scipp`
372    - `from_nddata` (static)
373    - `to_nddata`
374    - `from_dataframe` (static)
375    - `to_dataframe`
376    """
377
378    def __init__(self, xnd=None, name=None):
379        """Xdataset constructor
380
381        *Parameters*
382
383        - **xnd** : Xdataset/Xndarray/list of Xndarray (default None),
384        - **name** : String (default None) - name of the Xdataset
385        """
386        self.name = name
387        match xnd:
388            case list():
389                self.xnd = xnd
390            case xdat if isinstance(xdat, Xdataset):
391                self.name = xdat.name
392                self.xnd = xdat.xnd
393            case xnda if isinstance(xnda, Xndarray):
394                self.xnd = [xnda]
395            case _:
396                self.xnd = []
397
398    def __repr__(self):
399        """return classname and number of value"""
400        return (
401            self.__class__.__name__
402            + "["
403            + str(len(self))
404            + "]\n"
405            + pprint.pformat(self.to_json(novalue=True, header=False, noshape=False))
406        )
407
408    def __str__(self):
409        """return json string format"""
410        return json.dumps(self.to_json())
411
412    def __eq__(self, other):
413        """equal if xnd are equal"""
414        for xnda in self.xnd:
415            if xnda not in other:
416                return False
417        for xnda in other.xnd:
418            if xnda not in self:
419                return False
420        return True
421
422    def __len__(self):
423        """number of Xndarray"""
424        return len(self.xnd)
425
426    def __contains__(self, item):
427        """item of xnd"""
428        return item in self.xnd
429
430    def __getitem__(self, selec):
431        """return Xndarray or tuple of Xndarray with selec:
432        - string : name of a xndarray,
433        - integer : index of a xndarray,
434        - index selector : index interval
435        - tuple : names or index"""
436        if selec is None or selec == "" or selec in ([], ()):
437            return self
438        if isinstance(selec, (list, tuple)) and len(selec) == 1:
439            selec = selec[0]
440        if isinstance(selec, tuple):
441            return [self[i] for i in selec]
442        if isinstance(selec, str):
443            return self.dic_xnd[selec]
444        if isinstance(selec, list):
445            return self[selec[0]][selec[1:]]
446        return self.xnd[selec]
447
448    def __delitem__(self, ind):
449        """remove a Xndarray (ind is index, name or tuple of names)."""
450        if isinstance(ind, int):
451            del self.xnd[ind]
452        elif isinstance(ind, str):
453            del self.xnd[self.names.index(ind)]
454        elif isinstance(ind, tuple):
455            ind_n = [self.names[i] if isinstance(i, int) else i for i in ind]
456            for i in ind_n:
457                del self[i]
458
459    def __copy__(self):
460        """Copy all the data"""
461        return self.__class__(self)
462
463    def parent(self, var):
464        """return the Xndarray parent (where the full_name is equal to the name)"""
465        if var.name in self.names:
466            return self[var.name]
467        return var
468
469    def dims(self, var, json_name=False):
470        """return the list of parent namedarrays of the links of a Xndarray
471
472        *parameters*
473
474        - **var**: string - full_name of the Xndarray
475        - **json_name**: boolean (defaut False) - if True return json_name else full_name
476        """
477        if var not in self.names:
478            return None
479        if self[var].add_name and not self[var].links:
480            return self.dims(self[var].name, json_name)
481        if var in self.namedarrays:
482            return [self[var].json_name if json_name else var]
483        if var not in self.variables + self.additionals:
484            return None
485        list_dims = []
486        for link in self[var].links:
487            list_dims += (
488                self.dims(link, json_name) if self.dims(link, json_name) else [link]
489            )
490        return list_dims
491
492    def shape_dims(self, var):
493        """return a shape with the dimensions associated to the var full_name"""
494        return (
495            [len(self[dim]) for dim in self.dims(var)]
496            if set(self.dims(var)) <= set(self.names)
497            else None
498        )
499
500    @property
501    def validity(self):
502        """return the validity state: 'inconsistent', 'undifined' or 'valid'"""
503        for xnda in self:
504            if xnda.mode in ["relative", "inconsistent"]:
505                return "undefined"
506        if self.undef_links or self.undef_vars:
507            return "inconsistent"
508        return "valid"
509
510    @property
511    def xtype(self):
512        """return the Xdataset type: 'meta', 'group', 'mono', 'multi'"""
513        if self.metadata and not (
514            self.additionals or self.variables or self.namedarrays
515        ):
516            return "meta"
517        if self.validity != "valid":
518            return "group"
519        match len(self.data_vars):
520            case 0:
521                return "group"
522            case 1:
523                return "mono"
524            case _:
525                return "multi"
526
527    @property
528    def dic_xnd(self):
529        """return a dict of Xndarray where key is the full_name"""
530        return {xnda.full_name: xnda for xnda in self.xnd}
531
532    @property
533    def length(self):
534        """return the max length of Xndarray"""
535        return max(len(xnda) for xnda in self.xnd)
536
537    @property
538    def names(self):
539        """return a tuple with the Xndarray full_name"""
540        return tuple(xnda.full_name for xnda in self.xnd)
541
542    @property
543    def partition(self):
544        """return a dict of Xndarray grouped with category"""
545        dic = {}
546        dic |= {"data_vars": list(self.data_vars)} if self.data_vars else {}
547        dic |= {"data_arrays": list(self.data_arrays)} if self.data_arrays else {}
548        dic |= {"dimensions": list(self.dimensions)} if self.dimensions else {}
549        dic |= {"coordinates": list(self.coordinates)} if self.coordinates else {}
550        dic |= {"additionals": list(self.additionals)} if self.additionals else {}
551        dic |= {"metadata": list(self.metadata)} if self.metadata else {}
552        dic |= {"uniques": list(self.uniques)} if self.uniques else {}
553        return dic
554
555    @property
556    def info(self):
557        """return a dict with Xdataset information"""
558        inf = {"name": self.name, "xtype": self.xtype} | self.partition
559        inf["validity"] = self.validity
560        inf["length"] = len(self[self.data_vars[0]]) if self.data_vars else 0
561        inf["width"] = len(self)
562        data = {
563            name: {key: val for key, val in self[name].info.items() if key != "name"}
564            for name in self.names
565        }
566        return {
567            "structure": {key: val for key, val in inf.items() if val},
568            "data": {key: val for key, val in data.items() if val},
569        }
570
571    @property
572    def tab_info(self):
573        """return a dict with Xdataset information for tabular interface"""
574        info = self.info
575        data = info["data"]
576        t_info = {}
577        if "dimensions" in info["structure"]:
578            t_info["dimensions"] = info["structure"]["dimensions"]
579        t_info["data"] = {
580            name: {
581                key: val
582                for key, val in data[name].items()
583                if key in ["shape", "xtype", "meta", "links"]
584            }
585            for name in data
586        }
587        return t_info
588
589    def to_canonical(self):
590        """remove optional links of the included Xndarray"""
591        for name in self.names:
592            if self[name].links in ([self[name].name], [name]):
593                self[name].links = None
594        for add in self.additionals:
595            if self[add].links in [self[self[add].name].links, [self[add].name]]:
596                self[add].links = None
597        for unic in self.uniques:
598            self[unic].links = None
599        return self
600
601    def to_ndarray(self, full_name):
602        """convert a Xndarray from a Xdataset in a np.ndarray"""
603        if self.shape_dims(full_name) is None:
604            data = self[full_name].ndarray
605        else:
606            data = self[full_name].darray.reshape(self.shape_dims(full_name))
607        if data.dtype.name[:8] == "datetime":
608            data = data.astype("datetime64[ns]")
609        return data
610
611    def to_darray(self, full_name):
612        """convert a Xndarray from a Xdataset in a flattened np.ndarray"""
613        data = self[full_name].darray
614        if data.dtype.name[:8] == "datetime":
615            data = data.astype("datetime64[ns]")
616        return data

Representation of a multidimensional Dataset

Attributes :

  • name : String - name of the Xdataset
  • xnd: list of Xndarray

dynamic values (@property)

methods

XdatasetCategory (@property)

*XdatasetInterface methods *

Xdataset(xnd=None, name=None)
378    def __init__(self, xnd=None, name=None):
379        """Xdataset constructor
380
381        *Parameters*
382
383        - **xnd** : Xdataset/Xndarray/list of Xndarray (default None),
384        - **name** : String (default None) - name of the Xdataset
385        """
386        self.name = name
387        match xnd:
388            case list():
389                self.xnd = xnd
390            case xdat if isinstance(xdat, Xdataset):
391                self.name = xdat.name
392                self.xnd = xdat.xnd
393            case xnda if isinstance(xnda, Xndarray):
394                self.xnd = [xnda]
395            case _:
396                self.xnd = []

Xdataset constructor

Parameters

  • xnd : Xdataset/Xndarray/list of Xndarray (default None),
  • name : String (default None) - name of the Xdataset
name = NotImplemented
def parent(self, var):
463    def parent(self, var):
464        """return the Xndarray parent (where the full_name is equal to the name)"""
465        if var.name in self.names:
466            return self[var.name]
467        return var

return the Xndarray parent (where the full_name is equal to the name)

def dims(self, var, json_name=False):
469    def dims(self, var, json_name=False):
470        """return the list of parent namedarrays of the links of a Xndarray
471
472        *parameters*
473
474        - **var**: string - full_name of the Xndarray
475        - **json_name**: boolean (defaut False) - if True return json_name else full_name
476        """
477        if var not in self.names:
478            return None
479        if self[var].add_name and not self[var].links:
480            return self.dims(self[var].name, json_name)
481        if var in self.namedarrays:
482            return [self[var].json_name if json_name else var]
483        if var not in self.variables + self.additionals:
484            return None
485        list_dims = []
486        for link in self[var].links:
487            list_dims += (
488                self.dims(link, json_name) if self.dims(link, json_name) else [link]
489            )
490        return list_dims

return the list of parent namedarrays of the links of a Xndarray

parameters

  • var: string - full_name of the Xndarray
  • json_name: boolean (defaut False) - if True return json_name else full_name
def shape_dims(self, var):
492    def shape_dims(self, var):
493        """return a shape with the dimensions associated to the var full_name"""
494        return (
495            [len(self[dim]) for dim in self.dims(var)]
496            if set(self.dims(var)) <= set(self.names)
497            else None
498        )

return a shape with the dimensions associated to the var full_name

validity
500    @property
501    def validity(self):
502        """return the validity state: 'inconsistent', 'undifined' or 'valid'"""
503        for xnda in self:
504            if xnda.mode in ["relative", "inconsistent"]:
505                return "undefined"
506        if self.undef_links or self.undef_vars:
507            return "inconsistent"
508        return "valid"

return the validity state: 'inconsistent', 'undifined' or 'valid'

xtype
510    @property
511    def xtype(self):
512        """return the Xdataset type: 'meta', 'group', 'mono', 'multi'"""
513        if self.metadata and not (
514            self.additionals or self.variables or self.namedarrays
515        ):
516            return "meta"
517        if self.validity != "valid":
518            return "group"
519        match len(self.data_vars):
520            case 0:
521                return "group"
522            case 1:
523                return "mono"
524            case _:
525                return "multi"

return the Xdataset type: 'meta', 'group', 'mono', 'multi'

dic_xnd
527    @property
528    def dic_xnd(self):
529        """return a dict of Xndarray where key is the full_name"""
530        return {xnda.full_name: xnda for xnda in self.xnd}

return a dict of Xndarray where key is the full_name

length
532    @property
533    def length(self):
534        """return the max length of Xndarray"""
535        return max(len(xnda) for xnda in self.xnd)

return the max length of Xndarray

names
537    @property
538    def names(self):
539        """return a tuple with the Xndarray full_name"""
540        return tuple(xnda.full_name for xnda in self.xnd)

return a tuple with the Xndarray full_name

partition
542    @property
543    def partition(self):
544        """return a dict of Xndarray grouped with category"""
545        dic = {}
546        dic |= {"data_vars": list(self.data_vars)} if self.data_vars else {}
547        dic |= {"data_arrays": list(self.data_arrays)} if self.data_arrays else {}
548        dic |= {"dimensions": list(self.dimensions)} if self.dimensions else {}
549        dic |= {"coordinates": list(self.coordinates)} if self.coordinates else {}
550        dic |= {"additionals": list(self.additionals)} if self.additionals else {}
551        dic |= {"metadata": list(self.metadata)} if self.metadata else {}
552        dic |= {"uniques": list(self.uniques)} if self.uniques else {}
553        return dic

return a dict of Xndarray grouped with category

info
555    @property
556    def info(self):
557        """return a dict with Xdataset information"""
558        inf = {"name": self.name, "xtype": self.xtype} | self.partition
559        inf["validity"] = self.validity
560        inf["length"] = len(self[self.data_vars[0]]) if self.data_vars else 0
561        inf["width"] = len(self)
562        data = {
563            name: {key: val for key, val in self[name].info.items() if key != "name"}
564            for name in self.names
565        }
566        return {
567            "structure": {key: val for key, val in inf.items() if val},
568            "data": {key: val for key, val in data.items() if val},
569        }

return a dict with Xdataset information

tab_info
571    @property
572    def tab_info(self):
573        """return a dict with Xdataset information for tabular interface"""
574        info = self.info
575        data = info["data"]
576        t_info = {}
577        if "dimensions" in info["structure"]:
578            t_info["dimensions"] = info["structure"]["dimensions"]
579        t_info["data"] = {
580            name: {
581                key: val
582                for key, val in data[name].items()
583                if key in ["shape", "xtype", "meta", "links"]
584            }
585            for name in data
586        }
587        return t_info

return a dict with Xdataset information for tabular interface

def to_canonical(self):
589    def to_canonical(self):
590        """remove optional links of the included Xndarray"""
591        for name in self.names:
592            if self[name].links in ([self[name].name], [name]):
593                self[name].links = None
594        for add in self.additionals:
595            if self[add].links in [self[self[add].name].links, [self[add].name]]:
596                self[add].links = None
597        for unic in self.uniques:
598            self[unic].links = None
599        return self

remove optional links of the included Xndarray

def to_ndarray(self, full_name):
601    def to_ndarray(self, full_name):
602        """convert a Xndarray from a Xdataset in a np.ndarray"""
603        if self.shape_dims(full_name) is None:
604            data = self[full_name].ndarray
605        else:
606            data = self[full_name].darray.reshape(self.shape_dims(full_name))
607        if data.dtype.name[:8] == "datetime":
608            data = data.astype("datetime64[ns]")
609        return data

convert a Xndarray from a Xdataset in a np.ndarray

def to_darray(self, full_name):
611    def to_darray(self, full_name):
612        """convert a Xndarray from a Xdataset in a flattened np.ndarray"""
613        data = self[full_name].darray
614        if data.dtype.name[:8] == "datetime":
615            data = data.astype("datetime64[ns]")
616        return data

convert a Xndarray from a Xdataset in a flattened np.ndarray

Inherited Members
ntv_numpy.xdataset.XdatasetCategory
xnd
data_arrays
dimensions
shape
coordinates
data_vars
namedarrays
variables
undef_vars
masks
data_add
metadata
uniques
additionals
group
add_group
ntv_numpy.xdataset.XdatasetInterface
read_json
to_json
to_xarray
from_xarray
to_scipp
from_scipp
to_nddata
from_nddata
to_dataframe
from_dataframe