ntv-numpy.ntv_numpy.data_array
@author: Philippe@loco-labs.io
The data_array
module is part of the ntv-numpy.ntv_numpy
package (specification document).
It contains the classes Darray
(abstract), Dfull
, Dcomplete
for the
representation of unidimensional arrays.
For more information, see the user guide or the github repository.
1# -*- coding: utf-8 -*- 2""" 3@author: Philippe@loco-labs.io 4 5The `data_array` module is part of the `ntv-numpy.ntv_numpy` package ([specification document]( 6https://loco-philippe.github.io/ES/JSON%20semantic%20format%20(JSON-NTV).htm)). 7 8It contains the classes `Darray` (abstract), `Dfull`, `Dcomplete` for the 9representation of unidimensional arrays. 10 11For more information, see the 12[user guide](https://loco-philippe.github.io/ntv-numpy/docs/user_guide.html) 13 or the [github repository](https://github.com/loco-philippe/ntv-numpy). 14 15""" 16 17#import datetime 18#from decimal import Decimal 19 20from abc import ABC, abstractmethod 21import json 22import numpy as np 23from json_ntv import Ntv, NtvConnector 24#from json_ntv import Ntv, ShapelyConnec, NtvConnector 25import pandas as pd 26 27 28class Darray(ABC): 29 ''' The Darray class is an abstract class used by `Dfull`and `Dcomplete` classes. 30 31 *Attributes :* 32 - **data** : np.ndarray - data after coding 33 - **ref**: int or string - reference to another Darray data 34 - **coding**: np.ndarray of int - mapping between data and the values 35 36 *dynamic values (@property)* 37 - `values` 38 39 *methods* 40 - `read_json` (staticmethod) 41 - `to_json` 42 ''' 43 44 def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False): 45 '''Darray constructor. 46 47 *Parameters* 48 49 - **data**: list, Darray or np.ndarray - data to represent (after coding) 50 - **ref** : String or integer (default None) - name or index of another Darray 51 - **coding**: List of integer (default None) - mapping between data and the list of values 52 - **dtype**: string (default None) - numpy.dtype to apply 53 ''' 54 if isinstance(data, Darray): 55 self.data = data.data 56 self.ref = data.ref 57 self.coding = data.coding 58 return 59 data = data if isinstance(data, (list, np.ndarray)) else [data] 60 if (len(data) > 0 and isinstance(data[0], (list, np.ndarray))) or unidim: 61 self.data = np.fromiter(data, dtype='object') 62 else: 63 self.data = np.array(data, dtype=dtype).reshape(-1) 64 self.ref = ref 65 self.coding = np.array(coding) 66 67 def __repr__(self): 68 '''return classname and number of value''' 69 return self.__class__.__name__ + '[' + str(len(self)) + ']' 70 71 def __str__(self): 72 '''return json string format''' 73 return json.dumps(self.to_json()) 74 75 def __eq__(self, other): 76 ''' equal if values are equal''' 77 return np.array_equal(self.values, other.values, equal_nan=False) 78 79 def __len__(self): 80 ''' len of values''' 81 return self._len_val 82 83 def __contains__(self, item): 84 ''' item of values''' 85 return item in self.values 86 87 def __getitem__(self, ind): 88 ''' return value item''' 89 if isinstance(ind, tuple): 90 return [self.values[i] for i in ind] 91 # return [copy(self.values[i]) for i in ind] 92 return self.values[ind] 93 # return copy(self.values[ind]) 94 95 def __copy__(self): 96 ''' Copy all the data ''' 97 return self.__class__(self) 98 99 @staticmethod 100 def read_json(val, dtype=None, unidim=False): 101 ''' return a Darray entity from a list of data. 102 103 *Parameters* 104 105 - **val**: list of data 106 - **dtype** : string (default None) - numpy.dtype to apply 107 ''' 108 val = val if isinstance(val, list) else [val] 109 if not val or not isinstance(val[0], list): 110 return Dfull(val, dtype=dtype, unidim=unidim) 111 match val: 112 case [data, ref, list(coding)] if (isinstance(ref, (int, str)) and 113 isinstance(coding[0], int) and 114 max(coding) < len(data)): 115 return None 116 case [data, ref] if (isinstance(data, list) and 117 isinstance(ref, (int, str))): 118 return None 119 case [data, list(coef)] if len(coef) == 1: 120 return None 121 case [data, list(coding)] if (isinstance(coding[0], int) and 122 max(coding) < len(data)): 123 return Dcomplete(data, None, coding, dtype=dtype, unidim=unidim) 124 case _: 125 return Dfull(val, dtype=dtype, unidim=unidim) 126 127 @abstractmethod 128 def to_json(self): 129 ''' return a JsonValue''' 130 131 @property 132 @abstractmethod 133 def values(self): 134 ''' return the list of values''' 135 136 @property 137 @abstractmethod 138 def _len_val(self): 139 '''return the length of the entity''' 140 141 142class Dfull(Darray): 143 ''' Representation of a one dimensional Array with full representation 144 145 *dynamic values (@property)* 146 - `values` 147 148 *methods* 149 - `read_json` (staticmethod) 150 - `to_json` 151 ''' 152 153 def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False): 154 '''Dfull constructor. 155 156 *Parameters* 157 158 - **data**: list, Darray or np.ndarray - data to represent (after coding) 159 - **ref** : unused 160 - **coding**: unused 161 - **dtype**: string (default None) - numpy.dtype to apply 162 ''' 163 super().__init__(data, dtype=dtype, unidim=unidim) 164 165 def to_json(self): 166 ''' return a JsonValue of the Dfull entity.''' 167 #return self.data.tolist() 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 179 180 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(np.frompyfunc(Ntv.from_obj, 1, 1)(data), 207 return_index=True, return_inverse=True) 208 data = data[idx] 209 super().__init__(data, coding=coding, dtype=dtype, unidim=unidim) 210 211 def to_json(self): 212 ''' return a JsonValue of the Dcomplete entity.''' 213 #return [self.data.tolist(), self.coding.tolist()] 214 return [Dutil.list_json(self.data), self.coding.tolist()] 215 216 @property 217 def values(self): 218 ''' return the list of values''' 219 return self.data[self.coding] 220 221 @property 222 def _len_val(self): 223 '''return the length of the Dcomplete entity''' 224 return len(self.coding) if self.coding.ndim > 0 else 0 225 226class Dutil: 227 '''np.ndarray utilities. 228 229 *static methods* 230 - `convert` 231 - `is_json` 232 - `ntv_val` 233 - `add_ext` 234 - `split_type` 235 - `ntv_type` 236 - `nda_ntv_type` 237 - `dtype` 238 - `json_ntv` 239 - `split_name` 240 - `split_json_name` 241 ''' 242 """DATATION_DT = {'date': 'datetime64[D]', 'year': 'datetime64[Y]', 243 'yearmonth': 'datetime64[M]', 244 'datetime': 'datetime64[s]', 'datetime[ms]': 'datetime64[ms]', 245 'datetime[us]': 'datetime64[us]', 'datetime[ns]': 'datetime64[ns]', 246 'datetime[ps]': 'datetime64[ps]', 'datetime[fs]': 'datetime64[fs]', 247 'timedelta': 'timedelta64[s]', 'timedelta[ms]': 'timedelta64[ms]', 248 'timedelta[us]': 'timedelta64[us]', 'timedelta[ns]': 'timedelta64[ns]', 249 'timedelta[ps]': 'timedelta64[ps]', 'timedelta[fs]': 'timedelta64[fs]', 250 'timedelta[D]': 'timedelta64[D]', 'timedelta[Y]': 'timedelta64[Y]', 251 'timedelta[M]': 'timedelta64[M]'} 252 DT_DATATION = {val: key for key, val in DATATION_DT.items()} 253 254 #CONNECTOR_DT = {'field': 'Series', 'tab': 'DataFrame'} 255 CONNECTOR_DT = {'field': 'Series', 'tab': 'DataFrame'} 256 DT_CONNECTOR = {val: key for key, val in CONNECTOR_DT.items()} 257 258 PYTHON_DT = {'array': 'list', 'time': 'datetime.time', 259 'object': 'dict', 'null': 'NoneType', 'decimal64': 'Decimal', 260 'ndarray': 'ndarray', 'narray': 'narray'} 261 DT_PYTHON = {val: key for key, val in PYTHON_DT.items()} 262 263 #OTHER_DT = {'boolean': 'bool', 'string': 'str'} 264 OTHER_DT = {'boolean': 'bool', 'string': 'str', 'base16': 'bytes'} 265 DT_OTHER = {val: key for key, val in OTHER_DT.items()} 266 267 LOCATION_DT = {'point': 'Point', 268 'line': 'LineString', 'polygon': 'Polygon'} 269 DT_LOCATION = {val: key for key, val in LOCATION_DT.items()} 270 271 NUMBER_DT = {'json': 'object', 'number': None, 'month': 'int', 'day': 'int', 272 'wday': 'int', 'yday': 'int', 'week': 'hour', 'minute': 'int', 273 'second': 'int'} 274 #STRING_DT = {'base16': 'str', 'base32': 'str', 'base64': 'str', 275 STRING_DT = {'base32': 'str', 'base64': 'str', 276 'period': 'str', 'duration': 'str', 'jpointer': 'str', 277 'uri': 'str', 'uriref': 'str', 'iri': 'str', 'iriref': 'str', 278 'email': 'str', 'regex': 'str', 'hostname': 'str', 'ipv4': 'str', 279 'ipv6': 'str', 'file': 'str', 'geojson': 'str', } 280 FORMAT_CLS = {'full': Dfull, 'complete': Dcomplete} 281 CONVERT_DT = {'object': 'object', 'array': 'object', 'json': 'object', 282 'number': 'float', 'boolean': 'bool', 'null': 'object', 283 'string': 'str', 'integer': 'int'} 284 STRUCT_DT = {'Ntv': 'object', 'NtvSingle': 'object', 'NtvList': 'object'} 285 286 DT_NTVTYPE = DT_DATATION | DT_LOCATION | DT_OTHER | DT_CONNECTOR | DT_PYTHON""" 287 288 @staticmethod 289 def equals(nself, nother): 290 '''return True if all elements are equals and dtype are equal''' 291 if not (isinstance(nself, np.ndarray) and isinstance(nother, np.ndarray)): 292 return False 293 if nself.dtype != nother.dtype or nself.shape != nother.shape: 294 return False 295 if len(nself.shape) == 0: 296 return True 297 if len(nself) != len(nother): 298 return False 299 if len(nself) == 0: 300 return True 301 if isinstance(nself[0], (np.ndarray, pd.Series, pd.DataFrame)): 302 SeriesConnec = NtvConnector.connector().get('SeriesConnec') 303 DataFrameConnec = NtvConnector.connector().get('DataFrameConnec') 304 equal = {np.ndarray: Dutil.equals, 305 pd.Series: SeriesConnec.equals, 306 pd.DataFrame: DataFrameConnec.equals} 307 for nps, npo in zip(nself, nother): 308 if not equal[type(nself[0])](nps, npo): 309 return False 310 return True 311 return np.array_equal(nself, nother) 312 313 @staticmethod 314 def list_json(nda): 315 '''return a JSON representation of a unidimensional np.ndarray''' 316 if len(nda) == 0: 317 return [] 318 if isinstance(nda[0], np.ndarray): 319 return [Dutil.list_json(arr) for arr in nda] 320 return nda.tolist() 321 322 """@staticmethod 323 def convert(ntv_type, nda, tojson=True, convert=True): 324 ''' convert np.ndarray with external NTVtype. 325 326 *Parameters* 327 328 - **ntv_type** : string - NTVtype deduced from the np.ndarray name_type and dtype, 329 - **nda** : np.ndarray to be converted. 330 - **tojson** : boolean (default True) - apply to json function 331 - **convert** : boolean (default True) - If True, convert json data with 332 non Numpy ntv_type into data with python type 333 ''' 334 if tojson: 335 match ntv_type: 336 case dat if dat in Dutil.DATATION_DT: 337 return nda.astype(Dutil.DATATION_DT[dat]).astype(str) 338 case 'bytes': 339 return nda.astype('bytes').astype(str) 340 case 'time': 341 return nda.astype(str) 342 case 'decimal64': 343 return nda.astype(float) 344 case 'geojson': 345 return np.frompyfunc(ShapelyConnec.to_geojson, 1, 1)(nda) 346 case _: 347 return nda 348 else: 349 match [ntv_type, convert]: 350 case [None, _]: 351 return nda 352 case [dat, _] if dat in Dutil.DATATION_DT: 353 return nda.astype(Dutil.DATATION_DT[dat]) 354 case [std, _] if std in Dutil.OTHER_DT: 355 return nda.astype(Dutil.OTHER_DT[std]) 356 case ['time', True]: 357 return np.frompyfunc(datetime.time.fromisoformat, 1, 1)(nda) 358 case ['decimal64', True]: 359 return np.frompyfunc(Decimal, 1, 1)(nda) 360 case ['narray', True]: 361 nar = np.frompyfunc(Ndarray.read_json, 1, 1)(nda) 362 return np.frompyfunc(Ndarray.to_ndarray, 1, 1)(nar) 363 case ['ndarray', True]: 364 return np.frompyfunc(Ndarray.read_json, 1, 1)(nda) 365 case [python, _] if python in Dutil.PYTHON_DT: 366 return nda.astype('object') 367 case [connec, True] if connec in Dutil.CONNECTOR_DT: 368 return np.fromiter([NtvConnector.uncast(nd, None, connec)[0] 369 for nd in nda], dtype='object') 370 case [('point' | 'line' | 'polygon' | 'geometry'), True]: 371 return np.frompyfunc(ShapelyConnec.to_geometry, 1, 1)(nda) 372 case [_, False]: 373 return nda.astype(Dutil.CONVERT_DT[ 374 Dutil.dtype(ntv_type, convert=False)]) 375 case _: 376 return nda.astype(Dutil.dtype(ntv_type)) 377 378 # float.fromhex(x.hex()) == x, bytes(bytearray.fromhex(x.hex())) == x"""
29class Darray(ABC): 30 ''' The Darray class is an abstract class used by `Dfull`and `Dcomplete` classes. 31 32 *Attributes :* 33 - **data** : np.ndarray - data after coding 34 - **ref**: int or string - reference to another Darray data 35 - **coding**: np.ndarray of int - mapping between data and the values 36 37 *dynamic values (@property)* 38 - `values` 39 40 *methods* 41 - `read_json` (staticmethod) 42 - `to_json` 43 ''' 44 45 def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False): 46 '''Darray constructor. 47 48 *Parameters* 49 50 - **data**: list, Darray or np.ndarray - data to represent (after coding) 51 - **ref** : String or integer (default None) - name or index of another Darray 52 - **coding**: List of integer (default None) - mapping between data and the list of values 53 - **dtype**: string (default None) - numpy.dtype to apply 54 ''' 55 if isinstance(data, Darray): 56 self.data = data.data 57 self.ref = data.ref 58 self.coding = data.coding 59 return 60 data = data if isinstance(data, (list, np.ndarray)) else [data] 61 if (len(data) > 0 and isinstance(data[0], (list, np.ndarray))) or unidim: 62 self.data = np.fromiter(data, dtype='object') 63 else: 64 self.data = np.array(data, dtype=dtype).reshape(-1) 65 self.ref = ref 66 self.coding = np.array(coding) 67 68 def __repr__(self): 69 '''return classname and number of value''' 70 return self.__class__.__name__ + '[' + str(len(self)) + ']' 71 72 def __str__(self): 73 '''return json string format''' 74 return json.dumps(self.to_json()) 75 76 def __eq__(self, other): 77 ''' equal if values are equal''' 78 return np.array_equal(self.values, other.values, equal_nan=False) 79 80 def __len__(self): 81 ''' len of values''' 82 return self._len_val 83 84 def __contains__(self, item): 85 ''' item of values''' 86 return item in self.values 87 88 def __getitem__(self, ind): 89 ''' return value item''' 90 if isinstance(ind, tuple): 91 return [self.values[i] for i in ind] 92 # return [copy(self.values[i]) for i in ind] 93 return self.values[ind] 94 # return copy(self.values[ind]) 95 96 def __copy__(self): 97 ''' Copy all the data ''' 98 return self.__class__(self) 99 100 @staticmethod 101 def read_json(val, dtype=None, unidim=False): 102 ''' return a Darray entity from a list of data. 103 104 *Parameters* 105 106 - **val**: list of data 107 - **dtype** : string (default None) - numpy.dtype to apply 108 ''' 109 val = val if isinstance(val, list) else [val] 110 if not val or not isinstance(val[0], list): 111 return Dfull(val, dtype=dtype, unidim=unidim) 112 match val: 113 case [data, ref, list(coding)] if (isinstance(ref, (int, str)) and 114 isinstance(coding[0], int) and 115 max(coding) < len(data)): 116 return None 117 case [data, ref] if (isinstance(data, list) and 118 isinstance(ref, (int, str))): 119 return None 120 case [data, list(coef)] if len(coef) == 1: 121 return None 122 case [data, list(coding)] if (isinstance(coding[0], int) and 123 max(coding) < len(data)): 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 Dfull
and 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
45 def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False): 46 '''Darray constructor. 47 48 *Parameters* 49 50 - **data**: list, Darray or np.ndarray - data to represent (after coding) 51 - **ref** : String or integer (default None) - name or index of another Darray 52 - **coding**: List of integer (default None) - mapping between data and the list of values 53 - **dtype**: string (default None) - numpy.dtype to apply 54 ''' 55 if isinstance(data, Darray): 56 self.data = data.data 57 self.ref = data.ref 58 self.coding = data.coding 59 return 60 data = data if isinstance(data, (list, np.ndarray)) else [data] 61 if (len(data) > 0 and isinstance(data[0], (list, np.ndarray))) or unidim: 62 self.data = np.fromiter(data, dtype='object') 63 else: 64 self.data = np.array(data, dtype=dtype).reshape(-1) 65 self.ref = ref 66 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
100 @staticmethod 101 def read_json(val, dtype=None, unidim=False): 102 ''' return a Darray entity from a list of data. 103 104 *Parameters* 105 106 - **val**: list of data 107 - **dtype** : string (default None) - numpy.dtype to apply 108 ''' 109 val = val if isinstance(val, list) else [val] 110 if not val or not isinstance(val[0], list): 111 return Dfull(val, dtype=dtype, unidim=unidim) 112 match val: 113 case [data, ref, list(coding)] if (isinstance(ref, (int, str)) and 114 isinstance(coding[0], int) and 115 max(coding) < len(data)): 116 return None 117 case [data, ref] if (isinstance(data, list) and 118 isinstance(ref, (int, str))): 119 return None 120 case [data, list(coef)] if len(coef) == 1: 121 return None 122 case [data, list(coding)] if (isinstance(coding[0], int) and 123 max(coding) < len(data)): 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
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 self.data.tolist() 169 return Dutil.list_json(self.data) 170 171 @property 172 def values(self): 173 ''' return the list of values''' 174 return self.data 175 176 @property 177 def _len_val(self): 178 '''return the length of the Dfull entity''' 179 return len(self.data) if self.data.ndim > 0 else 0
Representation of a one dimensional Array with full representation
dynamic values (@property)
methods
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
166 def to_json(self): 167 ''' return a JsonValue of the Dfull entity.''' 168 #return self.data.tolist() 169 return Dutil.list_json(self.data)
return a JsonValue of the Dfull entity.
182class Dcomplete(Darray): 183 ''' Representation of a one dimensional Array with full representation 184 185 *dynamic values (@property)* 186 - `values` 187 188 *methods* 189 - `read_json` (staticmethod) 190 - `to_json` 191 ''' 192 193 def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False): 194 '''Dcomplete constructor. 195 196 *Parameters* 197 198 - **data**: list, Darray or np.ndarray - data to represent (after coding) 199 - **ref** : unused 200 - **coding**: List of integer (default None) - mapping between data and the list of values 201 - **dtype**: string (default None) - numpy.dtype to apply 202 ''' 203 if coding is None: 204 try: 205 data, coding = np.unique(data, return_inverse=True) 206 except (TypeError, ValueError): 207 dat, idx, coding = np.unique(np.frompyfunc(Ntv.from_obj, 1, 1)(data), 208 return_index=True, return_inverse=True) 209 data = data[idx] 210 super().__init__(data, coding=coding, dtype=dtype, unidim=unidim) 211 212 def to_json(self): 213 ''' return a JsonValue of the Dcomplete entity.''' 214 #return [self.data.tolist(), self.coding.tolist()] 215 return [Dutil.list_json(self.data), self.coding.tolist()] 216 217 @property 218 def values(self): 219 ''' return the list of values''' 220 return self.data[self.coding] 221 222 @property 223 def _len_val(self): 224 '''return the length of the Dcomplete entity''' 225 return len(self.coding) if self.coding.ndim > 0 else 0
Representation of a one dimensional Array with full representation
dynamic values (@property)
methods
193 def __init__(self, data, ref=None, coding=None, dtype=None, unidim=False): 194 '''Dcomplete constructor. 195 196 *Parameters* 197 198 - **data**: list, Darray or np.ndarray - data to represent (after coding) 199 - **ref** : unused 200 - **coding**: List of integer (default None) - mapping between data and the list of values 201 - **dtype**: string (default None) - numpy.dtype to apply 202 ''' 203 if coding is None: 204 try: 205 data, coding = np.unique(data, return_inverse=True) 206 except (TypeError, ValueError): 207 dat, idx, coding = np.unique(np.frompyfunc(Ntv.from_obj, 1, 1)(data), 208 return_index=True, return_inverse=True) 209 data = data[idx] 210 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
212 def to_json(self): 213 ''' return a JsonValue of the Dcomplete entity.''' 214 #return [self.data.tolist(), self.coding.tolist()] 215 return [Dutil.list_json(self.data), self.coding.tolist()]
return a JsonValue of the Dcomplete entity.
227class Dutil: 228 '''np.ndarray utilities. 229 230 *static methods* 231 - `convert` 232 - `is_json` 233 - `ntv_val` 234 - `add_ext` 235 - `split_type` 236 - `ntv_type` 237 - `nda_ntv_type` 238 - `dtype` 239 - `json_ntv` 240 - `split_name` 241 - `split_json_name` 242 ''' 243 """DATATION_DT = {'date': 'datetime64[D]', 'year': 'datetime64[Y]', 244 'yearmonth': 'datetime64[M]', 245 'datetime': 'datetime64[s]', 'datetime[ms]': 'datetime64[ms]', 246 'datetime[us]': 'datetime64[us]', 'datetime[ns]': 'datetime64[ns]', 247 'datetime[ps]': 'datetime64[ps]', 'datetime[fs]': 'datetime64[fs]', 248 'timedelta': 'timedelta64[s]', 'timedelta[ms]': 'timedelta64[ms]', 249 'timedelta[us]': 'timedelta64[us]', 'timedelta[ns]': 'timedelta64[ns]', 250 'timedelta[ps]': 'timedelta64[ps]', 'timedelta[fs]': 'timedelta64[fs]', 251 'timedelta[D]': 'timedelta64[D]', 'timedelta[Y]': 'timedelta64[Y]', 252 'timedelta[M]': 'timedelta64[M]'} 253 DT_DATATION = {val: key for key, val in DATATION_DT.items()} 254 255 #CONNECTOR_DT = {'field': 'Series', 'tab': 'DataFrame'} 256 CONNECTOR_DT = {'field': 'Series', 'tab': 'DataFrame'} 257 DT_CONNECTOR = {val: key for key, val in CONNECTOR_DT.items()} 258 259 PYTHON_DT = {'array': 'list', 'time': 'datetime.time', 260 'object': 'dict', 'null': 'NoneType', 'decimal64': 'Decimal', 261 'ndarray': 'ndarray', 'narray': 'narray'} 262 DT_PYTHON = {val: key for key, val in PYTHON_DT.items()} 263 264 #OTHER_DT = {'boolean': 'bool', 'string': 'str'} 265 OTHER_DT = {'boolean': 'bool', 'string': 'str', 'base16': 'bytes'} 266 DT_OTHER = {val: key for key, val in OTHER_DT.items()} 267 268 LOCATION_DT = {'point': 'Point', 269 'line': 'LineString', 'polygon': 'Polygon'} 270 DT_LOCATION = {val: key for key, val in LOCATION_DT.items()} 271 272 NUMBER_DT = {'json': 'object', 'number': None, 'month': 'int', 'day': 'int', 273 'wday': 'int', 'yday': 'int', 'week': 'hour', 'minute': 'int', 274 'second': 'int'} 275 #STRING_DT = {'base16': 'str', 'base32': 'str', 'base64': 'str', 276 STRING_DT = {'base32': 'str', 'base64': 'str', 277 'period': 'str', 'duration': 'str', 'jpointer': 'str', 278 'uri': 'str', 'uriref': 'str', 'iri': 'str', 'iriref': 'str', 279 'email': 'str', 'regex': 'str', 'hostname': 'str', 'ipv4': 'str', 280 'ipv6': 'str', 'file': 'str', 'geojson': 'str', } 281 FORMAT_CLS = {'full': Dfull, 'complete': Dcomplete} 282 CONVERT_DT = {'object': 'object', 'array': 'object', 'json': 'object', 283 'number': 'float', 'boolean': 'bool', 'null': 'object', 284 'string': 'str', 'integer': 'int'} 285 STRUCT_DT = {'Ntv': 'object', 'NtvSingle': 'object', 'NtvList': 'object'} 286 287 DT_NTVTYPE = DT_DATATION | DT_LOCATION | DT_OTHER | DT_CONNECTOR | DT_PYTHON""" 288 289 @staticmethod 290 def equals(nself, nother): 291 '''return True if all elements are equals and dtype are equal''' 292 if not (isinstance(nself, np.ndarray) and isinstance(nother, np.ndarray)): 293 return False 294 if nself.dtype != nother.dtype or nself.shape != nother.shape: 295 return False 296 if len(nself.shape) == 0: 297 return True 298 if len(nself) != len(nother): 299 return False 300 if len(nself) == 0: 301 return True 302 if isinstance(nself[0], (np.ndarray, pd.Series, pd.DataFrame)): 303 SeriesConnec = NtvConnector.connector().get('SeriesConnec') 304 DataFrameConnec = NtvConnector.connector().get('DataFrameConnec') 305 equal = {np.ndarray: Dutil.equals, 306 pd.Series: SeriesConnec.equals, 307 pd.DataFrame: DataFrameConnec.equals} 308 for nps, npo in zip(nself, nother): 309 if not equal[type(nself[0])](nps, npo): 310 return False 311 return True 312 return np.array_equal(nself, nother) 313 314 @staticmethod 315 def list_json(nda): 316 '''return a JSON representation of a unidimensional np.ndarray''' 317 if len(nda) == 0: 318 return [] 319 if isinstance(nda[0], np.ndarray): 320 return [Dutil.list_json(arr) for arr in nda] 321 return nda.tolist() 322 323 """@staticmethod 324 def convert(ntv_type, nda, tojson=True, convert=True): 325 ''' convert np.ndarray with external NTVtype. 326 327 *Parameters* 328 329 - **ntv_type** : string - NTVtype deduced from the np.ndarray name_type and dtype, 330 - **nda** : np.ndarray to be converted. 331 - **tojson** : boolean (default True) - apply to json function 332 - **convert** : boolean (default True) - If True, convert json data with 333 non Numpy ntv_type into data with python type 334 ''' 335 if tojson: 336 match ntv_type: 337 case dat if dat in Dutil.DATATION_DT: 338 return nda.astype(Dutil.DATATION_DT[dat]).astype(str) 339 case 'bytes': 340 return nda.astype('bytes').astype(str) 341 case 'time': 342 return nda.astype(str) 343 case 'decimal64': 344 return nda.astype(float) 345 case 'geojson': 346 return np.frompyfunc(ShapelyConnec.to_geojson, 1, 1)(nda) 347 case _: 348 return nda 349 else: 350 match [ntv_type, convert]: 351 case [None, _]: 352 return nda 353 case [dat, _] if dat in Dutil.DATATION_DT: 354 return nda.astype(Dutil.DATATION_DT[dat]) 355 case [std, _] if std in Dutil.OTHER_DT: 356 return nda.astype(Dutil.OTHER_DT[std]) 357 case ['time', True]: 358 return np.frompyfunc(datetime.time.fromisoformat, 1, 1)(nda) 359 case ['decimal64', True]: 360 return np.frompyfunc(Decimal, 1, 1)(nda) 361 case ['narray', True]: 362 nar = np.frompyfunc(Ndarray.read_json, 1, 1)(nda) 363 return np.frompyfunc(Ndarray.to_ndarray, 1, 1)(nar) 364 case ['ndarray', True]: 365 return np.frompyfunc(Ndarray.read_json, 1, 1)(nda) 366 case [python, _] if python in Dutil.PYTHON_DT: 367 return nda.astype('object') 368 case [connec, True] if connec in Dutil.CONNECTOR_DT: 369 return np.fromiter([NtvConnector.uncast(nd, None, connec)[0] 370 for nd in nda], dtype='object') 371 case [('point' | 'line' | 'polygon' | 'geometry'), True]: 372 return np.frompyfunc(ShapelyConnec.to_geometry, 1, 1)(nda) 373 case [_, False]: 374 return nda.astype(Dutil.CONVERT_DT[ 375 Dutil.dtype(ntv_type, convert=False)]) 376 case _: 377 return nda.astype(Dutil.dtype(ntv_type)) 378 379 # float.fromhex(x.hex()) == x, bytes(bytearray.fromhex(x.hex())) == x"""
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
289 @staticmethod 290 def equals(nself, nother): 291 '''return True if all elements are equals and dtype are equal''' 292 if not (isinstance(nself, np.ndarray) and isinstance(nother, np.ndarray)): 293 return False 294 if nself.dtype != nother.dtype or nself.shape != nother.shape: 295 return False 296 if len(nself.shape) == 0: 297 return True 298 if len(nself) != len(nother): 299 return False 300 if len(nself) == 0: 301 return True 302 if isinstance(nself[0], (np.ndarray, pd.Series, pd.DataFrame)): 303 SeriesConnec = NtvConnector.connector().get('SeriesConnec') 304 DataFrameConnec = NtvConnector.connector().get('DataFrameConnec') 305 equal = {np.ndarray: Dutil.equals, 306 pd.Series: SeriesConnec.equals, 307 pd.DataFrame: DataFrameConnec.equals} 308 for nps, npo in zip(nself, nother): 309 if not equal[type(nself[0])](nps, npo): 310 return False 311 return True 312 return np.array_equal(nself, nother)
return True if all elements are equals and dtype are equal
314 @staticmethod 315 def list_json(nda): 316 '''return a JSON representation of a unidimensional np.ndarray''' 317 if len(nda) == 0: 318 return [] 319 if isinstance(nda[0], np.ndarray): 320 return [Dutil.list_json(arr) for arr in nda] 321 return nda.tolist()
return a JSON representation of a unidimensional np.ndarray