python.observation.dataset_interface
Created on Sun Oct 2 22:24:59 2022
@author: philippe@loco-labs.io
The python.observation.dataset_interface
module contains the DatasetInterface
class
(python.observation.dataset.Dataset
methods).
1# -*- coding: utf-8 -*- 2""" 3Created on Sun Oct 2 22:24:59 2022 4 5@author: philippe@loco-labs.io 6 7The `python.observation.dataset_interface` module contains the `DatasetInterface` class 8(`python.observation.dataset.Dataset` methods). 9""" 10 11# %% declarations 12import csv 13import math 14import json 15import xarray 16import numpy as np 17import matplotlib.pyplot as plt 18from tabulate import tabulate 19 20from json_ntv.ntv import NtvList, NtvJsonEncoder 21from observation.field import Field 22from observation.util import util 23 24#import sys 25#print("In module dataset_interface sys.path[0], __package__ ==", sys.path[0], __package__) 26#print("In module dataset_interface __package__, __name__ ==", __package__, __name__) 27 28 29class DatasetError(Exception): 30 ''' Dataset Exception''' 31 # pass 32 33 34class DatasetInterface: 35 '''this class includes Dataset methods : 36 37 - `DatasetInterface.json` 38 - `DatasetInterface.plot` 39 - `DatasetInterface.to_obj` 40 - `DatasetInterface.to_csv` 41 - `DatasetInterface.to_file` 42 - `DatasetInterface.to_xarray` 43 - `DatasetInterface.to_dataframe` 44 - `DatasetInterface.view` 45 - `DatasetInterface.vlist` 46 - `DatasetInterface.voxel` 47 ''' 48 49 def json(self, **kwargs): 50 ''' 51 Return json dict, json string or Cbor binary. 52 53 *Parameters (kwargs)* 54 55 - **encoded** : boolean (default False) - choice for return format 56 (string/bytes if True, dict else) 57 - **format** : string (default 'json')- choice for return format (json, cbor) 58 - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder 59 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 60 if 'default' each index has keys, if 'optimize' keys are optimized, 61 if 'dict' dict format is used, if 'nokeys' keys are absent 62 - **name** : boolean (default False) - if False, default index name are not included 63 - **geojson** : boolean (default False) - geojson for LocationValue if True 64 65 *Returns* : string or dict''' 66 return self.to_obj(**kwargs) 67 68 def plot(self, varname=None, idxname=None, order=None, line=True, size=5, marker='o', maxlen=20): 69 ''' 70 This function visualize data with line or colormesh. 71 72 *Parameters* 73 74 - **varname** : string (default none) - Name of the variable to use. If None, 75 first lvarname is used. 76 - **line** : Boolean (default True) - Choice line or colormesh. 77 - **order** : list (defaut None) - order of the axes (x, y, hue or col) 78 - **size** : int (defaut 5) - plot size 79 - **marker** : Char (default 'o') - Symbol for each point. 80 - **maxlen** : Integer (default 20) - maximum length for string 81 82 *Returns* 83 84 - **None** ''' 85 if not self.consistent: 86 return None 87 if idxname: 88 idxname = [name for name in idxname if len( 89 self.nindex(name).codec) > 1] 90 #xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=[util.cast],## 91 xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=None, 92 dtype='str', npdtype='str', maxlen=maxlen, coord=True) 93 if not order: 94 order = [0, 1, 2] 95 96 if len(xar.dims) == 1: 97 xar.plot.line(x=xar.dims[0]+'_row', size=size, marker=marker) 98 elif len(xar.dims) == 2 and line: 99 xar.plot.line(x=xar.dims[order[0]] + '_row', 100 xticks=list(xar.coords[xar.dims[0]+'_row'].values), 101 hue=xar.dims[order[1]], size=size, marker=marker) 102 elif len(xar.dims) == 2 and not line: 103 xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row', 104 xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values), 105 yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values), 106 size=size) 107 elif len(xar.dims) == 3 and line: 108 xar.plot.line(x=xar.dims[order[0]] + '_row', col=xar.dims[order[1]], 109 xticks=list( 110 xar.coords[xar.dims[order[0]]+'_row'].values), 111 hue=xar.dims[order[2]], col_wrap=2, size=size, marker=marker) 112 elif len(xar.dims) == 3 and not line: 113 xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row', 114 xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values), 115 yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values), 116 col=xar.dims[order[2]], col_wrap=2, size=size) 117 plt.show() 118 return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) for i in range(len(xar.dims))} 119 120 def to_csv(self, filename, optcsv={'quoting': csv.QUOTE_NONNUMERIC}, **kwargs): 121 ''' 122 Generate csv file to display data. 123 124 *Parameters* 125 126 - **filename** : string - file name (with path) 127 - **optcsv** : parameter for csv.writer 128 129 *Parameters (kwargs)* 130 131 - **name=listcode** : element (default None) - eg location='ns' 132 - listcode : string with Code for each index (j: json, n: name, s: simple). 133 - name : name of the index 134 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 135 - **header** : Boolean (default : True) - If True, first line with names 136 - **optcsv** : parameter for csv.writer 137 - **ifunc** : function (default None) - function to apply to indexes 138 - **other kwargs** : parameter for ifunc 139 140 *Returns* : size of csv file ''' 141 size = 0 142 if not optcsv: 143 optcsv = {} 144 tab = self._to_tab(**kwargs) 145 with open(filename, 'w', newline='', encoding="utf-8") as csvfile: 146 writer = csv.writer(csvfile, **optcsv) 147 for lign in tab: 148 size += writer.writerow(lign) 149 return size 150 151 def to_dataframe(self, info=False, idx=None, fillvalue='?', fillextern=True, 152 lisfunc=None, name=None, numeric=False, npdtype=None, **kwargs): 153 ''' 154 Complete the Object and generate a Pandas DataFrame with the dimension define by idx. 155 156 *Parameters* 157 158 - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray 159 - **idx** : list (default none) - list of idx to be completed. If [], 160 self.primary is used. 161 - **fillvalue** : object (default '?') - value used for the new extval 162 - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value 163 - **lisfunc** : function (default none) - list of function to apply to indexes before export 164 - **name** : string (default None) - DataArray name. If None, variable name 165 - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values. 166 - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None) 167 - **kwargs** : parameter for lisfunc 168 169 *Returns* : pandas.DataFrame ''' 170 if self.consistent: 171 return self.to_xarray(info=info, idx=idx, fillvalue=fillvalue, 172 fillextern=fillextern, lisfunc=lisfunc, name=name, 173 numeric=numeric, npdtype=npdtype, **kwargs 174 ).to_dataframe(name=name) 175 return None 176 177 def to_file(self, filename, **kwargs): 178 '''Generate file to display data. 179 180 *Parameters (kwargs)* 181 182 - **filename** : string - file name (with path) 183 - **kwargs** : see 'to_ntv' parameters 184 185 *Returns* : Integer - file lenght (bytes) ''' 186 option = {'format': 'cbor', 'modecodec': 'optimize'} | kwargs | {'encoded': True} 187 data = self.to_ntv(modecodec=option['modecodec']).to_obj(**option) 188 if option['format'] == 'cbor': 189 size = len(data) 190 with open(filename, 'wb') as file: 191 file.write(data) 192 else: 193 size = len(bytes(data, 'UTF-8')) 194 with open(filename, 'w', newline='', encoding="utf-8") as file: 195 file.write(data) 196 return size 197 198 def to_ntv(self, modecodec='optimize', def_type='json', name=False): 199 '''Return a Ntv tab value (whithout name) . 200 201 *Parameters (kwargs)* 202 203 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 204 if 'default' each index has keys, if 'optimize' keys are optimized, 205 if 'dict' dict format is used, if 'nokeys' keys are absent 206 - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet 207 - **name** : boolean (default False) - if False, default index name are not included 208 209 210 *Returns* : Ntv object''' 211 idxname = [name or iname != 'i' + str(i) for i, iname in enumerate(self.lname)] 212 if modecodec != 'optimize': 213 lis = [index.to_ntv(modecodec=modecodec, name=iname) 214 for index, iname in zip(self.lindex, idxname)] 215 else: 216 lis = [] 217 indexinfos = self.indexinfos() 218 for idx, inf, iname in zip(self.lindex, indexinfos, idxname): 219 coef = Field.encode_coef(idx.keys) 220 if inf['cat'] == 'unique': 221 lis.append(idx.to_ntv(name=iname)) 222 elif inf['cat'] == 'coupled': 223 idx_coup = idx.setkeys(self.lindex[inf['parent']].keys, inplace=False) 224 lis.append(idx_coup.to_ntv(parent=inf['parent'], name=iname)) 225 elif coef: 226 lis.append(idx.to_ntv(keys=[coef], name=iname)) 227 elif inf['parent'] == -1: # cat='variable' or 'secondary' 228 if idx.keys == list(range(len(self))): 229 lis.append(idx.to_ntv(modecodec='full', name=iname)) 230 else: 231 lis.append(idx.to_ntv(modecodec='default', name=iname)) 232 else: # derived 233 if len(self.lindex[inf['parent']].codec) == len(self): 234 lis.append(idx.to_ntv(modecodec='default', name=iname)) 235 #elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): # periodic derived 236 # lis.append(Field.to_ntv(idx, parent=inf['parent'], name=iname)) 237 else: #derived 238 keys = idx.derkeys(self.lindex[inf['parent']]) 239 lis.append(idx.to_ntv(keys=keys, parent=inf['parent'], name=iname)) 240 return NtvList(lis, None, ntv_type=def_type) 241 242 """def to_obj(self, **kwargs): 243 '''Return a formatted object (json string, cbor bytes or json dict). 244 245 *Parameters (kwargs)* 246 247 - **encoded** : boolean (default False) - choice for return format 248 (string/bytes if True, dict else) 249 - **format** : string (default 'json')- choice for return format (json, cbor) 250 - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder 251 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 252 if 'default' each index has keys, if 'optimize' keys are optimized, 253 if 'dict' dict format is used, if 'nokeys' keys are absent 254 - **name** : boolean (default False) - if False, default index name are not included 255 - **fullvar** : boolean (default True) - if True and modecodec='optimize, 256 variable index is with a full codec 257 - **geojson** : boolean (default False) - geojson for LocationValue if True 258 - **id** : integer (default None) - Observation.id if Dataset is attached to an Observation 259 260 *Returns* : string, bytes or dict''' 261 option = {'modecodec': 'optimize', 'encoded': False, 262 'format': 'json', 'codif': ES.codeb, 'name': False, 263 'geojson': False, 'fullvar': True, 'id': None} | kwargs 264 option2 = {'encoded': False, 'format': 'json', 265 'codif': option['codif'], 'geojson': option['geojson'], 266 'modecodec': option['modecodec'], 'fullvar': option['fullvar']} 267 if option['modecodec'] == 'dict': 268 lis = {} 269 for idx in self.lindex: 270 name, dicval = list(idx.to_dict_obj(**option2).items())[0] 271 if name in self.lvarname: 272 dicval['var'] = True 273 lis[name] = dicval 274 elif option['modecodec'] == 'ndjson': 275 if not option['id']: 276 raise DatasetError("an id is necessary for 'ndjson'") 277 lis = [] 278 for rec in self: 279 lis.append({ES.id: option[ES.id]} | 280 {name: util.json(val, encoded=False, typevalue=None, 281 simpleval=False, modecodec='ndjson', 282 untyped=False, datetime=False, 283 geojson=False) 284 for name, val in zip(self.lname, rec)}) 285 else: 286 indexname = [option['name'] or name != 'i' + str(i) 287 for i, name in enumerate(self.lname)] 288 if option['modecodec'] != 'optimize': 289 lis = [idx.to_obj(name=iname, **option2) 290 for idx, iname in zip(self.lindex, indexname)] 291 else: 292 lis = self._optimize_obj(indexname, **option2) 293 294 if option['encoded'] and option['format'] == 'json': 295 return json.dumps(lis, cls=FieldEncoder) 296 if option['encoded'] and option['format'] == 'cbor': 297 return cbor2.dumps(lis, datetime_as_timestamp=True, 298 timezone=datetime.timezone.utc, canonical=True) 299 return lis""" 300 301 def to_xarray(self, info=False, idxname=None, varname=None, fillvalue='?', 302 fillextern=True, lisfunc=None, name=None, numeric=False, 303 npdtype=None, attrs=None, coord=False, **kwargs): 304 ''' 305 Complete the Object and generate a Xarray DataArray with the dimension define by idx. 306 Only the first variable is incuded. 307 308 *Parameters* 309 310 - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray 311 - **idxname** : list (default none) - list of idx to be completed. If None, 312 self.primary is used. 313 - **varname** : string (default none) - Name of the variable to use. If None, 314 first lvarname is used. 315 - **fillvalue** : object (default '?') - value used for the new extval 316 - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value 317 - **lisfunc** : function (default none) - list of function to apply to indexes before export 318 - **name** : string (default None) - DataArray name. If None, variable name 319 - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values. 320 - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None) 321 - **attrs** : dict (default None) - attributes for the DataArray 322 - **coord** : boolean (default False) - if True, add derivated coords 323 - **kwargs** : parameter for lisfunc 324 325 *Returns* : DataArray ''' 326 option = {'dtype': None} | kwargs 327 if not self.consistent: 328 raise DatasetError("Dataset not consistent") 329 if idxname is None or idxname == []: 330 idxname = self.primaryname 331 ilf = self.full(idxname=idxname, varname=varname, fillvalue=fillvalue, 332 fillextern=fillextern, inplace=False) 333 ilf.setcanonorder() 334 if not varname and len(ilf.lvarname) != 0: 335 varname = ilf.lvarname[0] 336 if not varname in ilf.lname: 337 ivar = -1 338 else: 339 ivar = ilf.lname.index(varname) 340 if isinstance(lisfunc, list) and len(lisfunc) == 1: 341 lisfunc = lisfunc * ilf.lenindex 342 elif isinstance(lisfunc, list) and len(lisfunc) != ilf.lenindex: 343 lisfunc = [None] * ilf.lenindex 344 elif not isinstance(lisfunc, list): 345 funcvar = lisfunc 346 lisfunc = [None] * ilf.lenindex 347 if ivar != -1: 348 lisfunc[ivar] = funcvar 349 lisfuncname = dict(zip(ilf.lname, lisfunc)) 350 coords = ilf._xcoord(idxname, ivar, lisfuncname, coord, **option) 351 dims = idxname 352 if numeric: 353 #lisfunc[ivar] = util.cast 354 fillvalue = math.nan 355 npdtype = 'float' 356 option['dtype'] = 'float' 357 if ivar == -1: 358 data = self.field(list(range(len(ilf)))).to_numpy(npdtype='int')\ 359 .reshape([len(ilf.nindex(name).codec) for name in idxname]) 360 else: 361 data = ilf.lindex[ivar]\ 362 .to_numpy(func=lisfunc[ivar], npdtype=npdtype, **option)\ 363 .reshape([len(ilf.nindex(name).codec) for name in idxname]) 364 if not name and ivar == -1: 365 name = ilf.name 366 elif not name: 367 name = ilf.lname[ivar] 368 if not isinstance(attrs, dict): 369 attrs = {} 370 for nam in ilf.lunicname: 371 attrs[nam] = ilf.nindex(nam).codec[0] 372 if info: 373 attrs |= ilf.indexinfos() 374 return xarray.DataArray(data, coords, dims, attrs=attrs, name=name) 375 376 def voxel(self, idxname=None, varname=None): 377 ''' 378 Plot not null values in a cube with voxels and return indexes values. 379 380 *Parameters* 381 382 - **idxname** : list (default none) - list of idx to be completed. If None, 383 self.primary is used. 384 - **varname** : string (default none) - Name of the variable to use. If None, 385 first lvarname is used. 386 387 *Returns* : **dict of indexes values** 388 ''' 389 if not self.consistent: 390 return None 391 if idxname is None or idxname == []: 392 idxname = self.primaryname 393 if varname is None and self.lvarname: 394 varname = self.lvarname[0] 395 if len(idxname) > 3: 396 raise DatasetError('number of idx > 3') 397 if len(idxname) == 2: 398 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 399 idxname += [' '] 400 elif len(idxname) == 1: 401 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 402 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 403 idxname += [' ', ' '] 404 xar = self.to_xarray(idxname=idxname, varname=varname, fillvalue='?', 405 fillextern=False, lisfunc=util.isNotEqual, tovalue='?') 406 axe = plt.figure().add_subplot(projection='3d') 407 axe.voxels(xar, edgecolor='k') 408 axe.set_xticks(np.arange(self.idxlen[self.idxname.index(xar.dims[0])])) 409 axe.set_yticks(np.arange(self.idxlen[self.idxname.index(xar.dims[1])])) 410 axe.set_zticks(np.arange(self.idxlen[self.idxname.index(xar.dims[2])])) 411 axe.set(xlabel=xar.dims[0][:8], 412 ylabel=xar.dims[1][:8], 413 zlabel=xar.dims[2][:8]) 414 plt.show() 415 self.delindex([' ', ' ']) 416 return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) 417 for i in range(len(xar.dims))} 418 419 def view(self, **kwargs): 420 ''' 421 Generate tabular list to display data. 422 423 *Parameters (kwargs)* 424 425 - **name=listcode** : element (default None) - eg location='ns' 426 - listcode : string with Code for each index (j: json, n: name, s: simple). 427 - name : name of the index 428 - **defcode** : String (default : 'j') - default list code (if 'all' is True) 429 - **all** : Boolean (default : True) - 'defcode apply to all indexes or none 430 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 431 - **header** : Boolean (default : True) - First line with names 432 - **width** : Integer (default None) - Number of characters displayed for each 433 attribute (all if None) 434 - **ifunc** : function (default None) - function to apply to indexes 435 - **tabulate params** : default 'tablefmt': 'simple', 'numalign': 'left', 436 'stralign': 'left', 'floatfmt': '.3f' - See tabulate module 437 - **other kwargs** : parameter for ifunc 438 439 *Returns* : list or html table (tabulate format) ''' 440 # print(kwargs) 441 opttab = {'defcode': 'j', 'all': True, 'lenres': 0, 'header': True} 442 optview = {'tablefmt': 'simple', 'numalign': 'decimal', 443 'stralign': 'left', 'floatfmt': '.2f'} 444 option = opttab | optview | kwargs 445 tab = self._to_tab(**option) 446 width = ({'width': None} | kwargs)['width'] 447 if width: 448 tab = [[(lambda x: x[:width] if isinstance(x, str) else x)(val) 449 for val in lig] for lig in tab] 450 return tabulate(tab, headers='firstrow', **{k: option[k] for k in optview}) 451 452 def vlist(self, *args, func=None, index=-1, **kwargs): 453 ''' 454 Apply a function to an index and return the result. 455 456 *Parameters* 457 458 - **func** : function (default none) - function to apply to extval or extidx 459 - **args, kwargs** : parameters for the function 460 - **index** : integer - index to update (index=-1 for first variable) 461 462 *Returns* : list of func result''' 463 if index == -1 and self.lvar: 464 return self.lvar[0].vlist(func, *args, **kwargs) 465 if index == -1 and self.lenindex == 1: 466 index = 0 467 return self.lindex[index].vlist(func, *args, **kwargs) 468 469 # %%internal 470 """def _optimize_obj(self, idxname, **option2): 471 '''return list object with optimize modecodec''' 472 indexinfos = self.indexinfos() 473 notkeys = True 474 lis = [] 475 if self.iscanonorder(): 476 notkeys = None 477 for idx, iname, inf in zip(self.lindex, idxname, indexinfos): 478 if inf['cat'] == 'unique': 479 lis.append(idx.tostdcodec(full=False).to_obj( 480 name=iname, **option2)) 481 elif inf['cat'] == 'primary': 482 lis.append(idx.to_obj(keys=notkeys, name=iname, **option2)) 483 elif inf['cat'] == 'coupled': 484 lis.append(idx.setkeys(self.lindex[inf['parent']].keys, inplace=False). 485 to_obj(parent=inf['parent'], name=iname, **option2)) 486 elif inf['parent'] == -1: # cat='variable' or 'secondary' 487 if option2['fullvar'] and inf['cat'] == 'variable' and not(inf['child']): 488 opt = option2 | {'modecodec': 'full'} 489 lis.append(idx.to_obj(name=iname, **opt)) 490 elif idx.keys == list(range(len(self))): 491 lis.append(idx.to_obj(name=iname, **option2)) 492 else: 493 lis.append(idx.to_obj(keys=True, name=iname, **option2)) 494 else: # derived 495 if len(self.lindex[inf['parent']].codec) == len(self): 496 lis.append(idx.to_obj(keys=True, name=iname, **option2)) 497 elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): 498 lis.append(idx.to_obj(parent=inf['parent'], 499 name=iname, **option2)) 500 else: # periodic derived 501 keys = idx.derkeys(self.lindex[inf['parent']]) 502 lis.append(idx.to_obj(keys=keys, parent=inf['parent'], 503 name=iname, **option2)) 504 return lis""" 505 506 def _to_tab(self, **kwargs): 507 ''' data preparation (dict of dict) for view or csv export. 508 Representation is included if : 509 - code is definie in the name element of the field 510 - or code is defined in 'defcode' element and 'all' element is True 511 512 *Parameters (kwargs)* 513 514 - **name=listcode** : element (default None) - eg location='ns' 515 - listcode : string with Code for each index (j: json, n: name, s: simple, f: ifunc). 516 - name : name of the index 517 - **defcode** : String (default : 'j') - default list code (if 'all' is True) 518 - **all** : Boolean (default : True) - 'defcode apply to all indexes or none 519 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 520 - **ifunc** : function (default None) - function to apply to indexes 521 - **other kwargs** : parameter for ifunc''' 522 523 option = {'defcode': 'j', 'all': True, 'lenres': 0, 'ifunc': None, 524 'header': True} | kwargs 525 tab = [] 526 reslist = [] 527 diccode = {'j': '', 'n': 'name-', 's': 'smpl-', 'f': 'func-'} 528 if option['header']: 529 for name in self.lname: 530 '''if name in option: 531 for char, code in diccode.items(): 532 if char in option[name]: 533 reslist.append(code + name) 534 elif option['all']: 535 for char, code in diccode.items(): 536 if char in option['defcode']: 537 reslist.append(code + name)''' 538 opt = name if name in option else 'defcode' 539 if opt != 'defcode' or option['all']: 540 for char, code in diccode.items(): 541 if char in option[opt]: 542 reslist.append(code + name) 543 tab.append(reslist) 544 lenres = option['lenres'] 545 if lenres == 0: 546 lenres = len(self) 547 for i in range(min(lenres, len(self))): 548 reslist = [] 549 for name in self.lname: 550 opt = name if name in option else 'defcode' 551 if opt != 'defcode' or option['all']: 552 for char, code in diccode.items(): 553 if char in option[opt]: 554 val = self.nindex(name).values[i] 555 if char == 'j': 556 #reslist.append(util.cast(val, dtype='json')) 557 reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder)) 558 elif char == 'n': 559 reslist.append(self.field.i_to_name(val)) 560 elif char == 's': 561 reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder)) 562 elif char == 'f': 563 reslist.append(util.funclist( 564 val, option['ifunc'], **kwargs)) 565 '''if name in option: 566 for char, code in diccode.items(): 567 if char in option[name]: 568 val = self.nindex(name).values[i] 569 if char == 'j': 570 #reslist.append(util.cast(val, dtype='json')) 571 reslist.append(self.field.s_to_e(val)) 572 elif char == 'n': 573 reslist.append(self.field.i_to_name(val)) 574 elif char == 's': 575 reslist.append( 576 json.dumps(self.field.s_to_e(val))) 577 elif char == 'f': 578 reslist.append(util.funclist( 579 val, option['ifunc'], **kwargs)) 580 elif option['all']: 581 for char, code in diccode.items(): 582 if char in option['defcode']: 583 val = self.nindex(name).values[i] 584 if char == 'j': 585 reslist.append(util.cast(val, dtype='json')) 586 elif char == 'n': 587 reslist.append(util.cast(val, dtype='name')) 588 elif char == 's': 589 reslist.append( 590 util.cast(val, dtype='json', string=True)) 591 elif char == 'f': 592 reslist.append(util.funclist( 593 val, option['ifunc'], **kwargs))''' 594 tab.append(reslist) 595 return tab 596 597 def _xcoord(self, axename, ivar, lisfuncname=None, coord=False, **kwargs): 598 ''' Coords generation for Xarray''' 599 #maxlen = kwargs.get('maxlen', 20) 600 info = self.indexinfos() 601 coords = {} 602 for i in range(self.lenindex): 603 fieldi = info[i] 604 iname = self.lname[i] 605 if fieldi['pparent'] == -1 or i == ivar: 606 continue 607 if isinstance(lisfuncname, dict) and len(lisfuncname) == self.lenindex: 608 funci = lisfuncname[iname] 609 else: 610 funci = None 611 if iname in axename: 612 coords[iname] = self.lindex[i].to_numpy( 613 func=funci, codec=True, **kwargs) 614 if coord: 615 coords[iname+'_row'] = (iname, 616 np.arange(len(coords[iname]))) 617 #coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=util.cast, 618 # codec=True, dtype='str', maxlen=maxlen)) 619 coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=str, codec=True)) 620 else: 621 self.lindex[i].setkeys( 622 self.lindex[fieldi['pparent']].keys) # !!! 623 coords[iname] = (self.lname[fieldi['pparent']], 624 self.lindex[i].to_numpy(func=funci, codec=True, **kwargs)) 625 return coords
Dataset Exception
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
- args
35class DatasetInterface: 36 '''this class includes Dataset methods : 37 38 - `DatasetInterface.json` 39 - `DatasetInterface.plot` 40 - `DatasetInterface.to_obj` 41 - `DatasetInterface.to_csv` 42 - `DatasetInterface.to_file` 43 - `DatasetInterface.to_xarray` 44 - `DatasetInterface.to_dataframe` 45 - `DatasetInterface.view` 46 - `DatasetInterface.vlist` 47 - `DatasetInterface.voxel` 48 ''' 49 50 def json(self, **kwargs): 51 ''' 52 Return json dict, json string or Cbor binary. 53 54 *Parameters (kwargs)* 55 56 - **encoded** : boolean (default False) - choice for return format 57 (string/bytes if True, dict else) 58 - **format** : string (default 'json')- choice for return format (json, cbor) 59 - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder 60 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 61 if 'default' each index has keys, if 'optimize' keys are optimized, 62 if 'dict' dict format is used, if 'nokeys' keys are absent 63 - **name** : boolean (default False) - if False, default index name are not included 64 - **geojson** : boolean (default False) - geojson for LocationValue if True 65 66 *Returns* : string or dict''' 67 return self.to_obj(**kwargs) 68 69 def plot(self, varname=None, idxname=None, order=None, line=True, size=5, marker='o', maxlen=20): 70 ''' 71 This function visualize data with line or colormesh. 72 73 *Parameters* 74 75 - **varname** : string (default none) - Name of the variable to use. If None, 76 first lvarname is used. 77 - **line** : Boolean (default True) - Choice line or colormesh. 78 - **order** : list (defaut None) - order of the axes (x, y, hue or col) 79 - **size** : int (defaut 5) - plot size 80 - **marker** : Char (default 'o') - Symbol for each point. 81 - **maxlen** : Integer (default 20) - maximum length for string 82 83 *Returns* 84 85 - **None** ''' 86 if not self.consistent: 87 return None 88 if idxname: 89 idxname = [name for name in idxname if len( 90 self.nindex(name).codec) > 1] 91 #xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=[util.cast],## 92 xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=None, 93 dtype='str', npdtype='str', maxlen=maxlen, coord=True) 94 if not order: 95 order = [0, 1, 2] 96 97 if len(xar.dims) == 1: 98 xar.plot.line(x=xar.dims[0]+'_row', size=size, marker=marker) 99 elif len(xar.dims) == 2 and line: 100 xar.plot.line(x=xar.dims[order[0]] + '_row', 101 xticks=list(xar.coords[xar.dims[0]+'_row'].values), 102 hue=xar.dims[order[1]], size=size, marker=marker) 103 elif len(xar.dims) == 2 and not line: 104 xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row', 105 xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values), 106 yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values), 107 size=size) 108 elif len(xar.dims) == 3 and line: 109 xar.plot.line(x=xar.dims[order[0]] + '_row', col=xar.dims[order[1]], 110 xticks=list( 111 xar.coords[xar.dims[order[0]]+'_row'].values), 112 hue=xar.dims[order[2]], col_wrap=2, size=size, marker=marker) 113 elif len(xar.dims) == 3 and not line: 114 xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row', 115 xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values), 116 yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values), 117 col=xar.dims[order[2]], col_wrap=2, size=size) 118 plt.show() 119 return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) for i in range(len(xar.dims))} 120 121 def to_csv(self, filename, optcsv={'quoting': csv.QUOTE_NONNUMERIC}, **kwargs): 122 ''' 123 Generate csv file to display data. 124 125 *Parameters* 126 127 - **filename** : string - file name (with path) 128 - **optcsv** : parameter for csv.writer 129 130 *Parameters (kwargs)* 131 132 - **name=listcode** : element (default None) - eg location='ns' 133 - listcode : string with Code for each index (j: json, n: name, s: simple). 134 - name : name of the index 135 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 136 - **header** : Boolean (default : True) - If True, first line with names 137 - **optcsv** : parameter for csv.writer 138 - **ifunc** : function (default None) - function to apply to indexes 139 - **other kwargs** : parameter for ifunc 140 141 *Returns* : size of csv file ''' 142 size = 0 143 if not optcsv: 144 optcsv = {} 145 tab = self._to_tab(**kwargs) 146 with open(filename, 'w', newline='', encoding="utf-8") as csvfile: 147 writer = csv.writer(csvfile, **optcsv) 148 for lign in tab: 149 size += writer.writerow(lign) 150 return size 151 152 def to_dataframe(self, info=False, idx=None, fillvalue='?', fillextern=True, 153 lisfunc=None, name=None, numeric=False, npdtype=None, **kwargs): 154 ''' 155 Complete the Object and generate a Pandas DataFrame with the dimension define by idx. 156 157 *Parameters* 158 159 - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray 160 - **idx** : list (default none) - list of idx to be completed. If [], 161 self.primary is used. 162 - **fillvalue** : object (default '?') - value used for the new extval 163 - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value 164 - **lisfunc** : function (default none) - list of function to apply to indexes before export 165 - **name** : string (default None) - DataArray name. If None, variable name 166 - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values. 167 - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None) 168 - **kwargs** : parameter for lisfunc 169 170 *Returns* : pandas.DataFrame ''' 171 if self.consistent: 172 return self.to_xarray(info=info, idx=idx, fillvalue=fillvalue, 173 fillextern=fillextern, lisfunc=lisfunc, name=name, 174 numeric=numeric, npdtype=npdtype, **kwargs 175 ).to_dataframe(name=name) 176 return None 177 178 def to_file(self, filename, **kwargs): 179 '''Generate file to display data. 180 181 *Parameters (kwargs)* 182 183 - **filename** : string - file name (with path) 184 - **kwargs** : see 'to_ntv' parameters 185 186 *Returns* : Integer - file lenght (bytes) ''' 187 option = {'format': 'cbor', 'modecodec': 'optimize'} | kwargs | {'encoded': True} 188 data = self.to_ntv(modecodec=option['modecodec']).to_obj(**option) 189 if option['format'] == 'cbor': 190 size = len(data) 191 with open(filename, 'wb') as file: 192 file.write(data) 193 else: 194 size = len(bytes(data, 'UTF-8')) 195 with open(filename, 'w', newline='', encoding="utf-8") as file: 196 file.write(data) 197 return size 198 199 def to_ntv(self, modecodec='optimize', def_type='json', name=False): 200 '''Return a Ntv tab value (whithout name) . 201 202 *Parameters (kwargs)* 203 204 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 205 if 'default' each index has keys, if 'optimize' keys are optimized, 206 if 'dict' dict format is used, if 'nokeys' keys are absent 207 - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet 208 - **name** : boolean (default False) - if False, default index name are not included 209 210 211 *Returns* : Ntv object''' 212 idxname = [name or iname != 'i' + str(i) for i, iname in enumerate(self.lname)] 213 if modecodec != 'optimize': 214 lis = [index.to_ntv(modecodec=modecodec, name=iname) 215 for index, iname in zip(self.lindex, idxname)] 216 else: 217 lis = [] 218 indexinfos = self.indexinfos() 219 for idx, inf, iname in zip(self.lindex, indexinfos, idxname): 220 coef = Field.encode_coef(idx.keys) 221 if inf['cat'] == 'unique': 222 lis.append(idx.to_ntv(name=iname)) 223 elif inf['cat'] == 'coupled': 224 idx_coup = idx.setkeys(self.lindex[inf['parent']].keys, inplace=False) 225 lis.append(idx_coup.to_ntv(parent=inf['parent'], name=iname)) 226 elif coef: 227 lis.append(idx.to_ntv(keys=[coef], name=iname)) 228 elif inf['parent'] == -1: # cat='variable' or 'secondary' 229 if idx.keys == list(range(len(self))): 230 lis.append(idx.to_ntv(modecodec='full', name=iname)) 231 else: 232 lis.append(idx.to_ntv(modecodec='default', name=iname)) 233 else: # derived 234 if len(self.lindex[inf['parent']].codec) == len(self): 235 lis.append(idx.to_ntv(modecodec='default', name=iname)) 236 #elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): # periodic derived 237 # lis.append(Field.to_ntv(idx, parent=inf['parent'], name=iname)) 238 else: #derived 239 keys = idx.derkeys(self.lindex[inf['parent']]) 240 lis.append(idx.to_ntv(keys=keys, parent=inf['parent'], name=iname)) 241 return NtvList(lis, None, ntv_type=def_type) 242 243 """def to_obj(self, **kwargs): 244 '''Return a formatted object (json string, cbor bytes or json dict). 245 246 *Parameters (kwargs)* 247 248 - **encoded** : boolean (default False) - choice for return format 249 (string/bytes if True, dict else) 250 - **format** : string (default 'json')- choice for return format (json, cbor) 251 - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder 252 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 253 if 'default' each index has keys, if 'optimize' keys are optimized, 254 if 'dict' dict format is used, if 'nokeys' keys are absent 255 - **name** : boolean (default False) - if False, default index name are not included 256 - **fullvar** : boolean (default True) - if True and modecodec='optimize, 257 variable index is with a full codec 258 - **geojson** : boolean (default False) - geojson for LocationValue if True 259 - **id** : integer (default None) - Observation.id if Dataset is attached to an Observation 260 261 *Returns* : string, bytes or dict''' 262 option = {'modecodec': 'optimize', 'encoded': False, 263 'format': 'json', 'codif': ES.codeb, 'name': False, 264 'geojson': False, 'fullvar': True, 'id': None} | kwargs 265 option2 = {'encoded': False, 'format': 'json', 266 'codif': option['codif'], 'geojson': option['geojson'], 267 'modecodec': option['modecodec'], 'fullvar': option['fullvar']} 268 if option['modecodec'] == 'dict': 269 lis = {} 270 for idx in self.lindex: 271 name, dicval = list(idx.to_dict_obj(**option2).items())[0] 272 if name in self.lvarname: 273 dicval['var'] = True 274 lis[name] = dicval 275 elif option['modecodec'] == 'ndjson': 276 if not option['id']: 277 raise DatasetError("an id is necessary for 'ndjson'") 278 lis = [] 279 for rec in self: 280 lis.append({ES.id: option[ES.id]} | 281 {name: util.json(val, encoded=False, typevalue=None, 282 simpleval=False, modecodec='ndjson', 283 untyped=False, datetime=False, 284 geojson=False) 285 for name, val in zip(self.lname, rec)}) 286 else: 287 indexname = [option['name'] or name != 'i' + str(i) 288 for i, name in enumerate(self.lname)] 289 if option['modecodec'] != 'optimize': 290 lis = [idx.to_obj(name=iname, **option2) 291 for idx, iname in zip(self.lindex, indexname)] 292 else: 293 lis = self._optimize_obj(indexname, **option2) 294 295 if option['encoded'] and option['format'] == 'json': 296 return json.dumps(lis, cls=FieldEncoder) 297 if option['encoded'] and option['format'] == 'cbor': 298 return cbor2.dumps(lis, datetime_as_timestamp=True, 299 timezone=datetime.timezone.utc, canonical=True) 300 return lis""" 301 302 def to_xarray(self, info=False, idxname=None, varname=None, fillvalue='?', 303 fillextern=True, lisfunc=None, name=None, numeric=False, 304 npdtype=None, attrs=None, coord=False, **kwargs): 305 ''' 306 Complete the Object and generate a Xarray DataArray with the dimension define by idx. 307 Only the first variable is incuded. 308 309 *Parameters* 310 311 - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray 312 - **idxname** : list (default none) - list of idx to be completed. If None, 313 self.primary is used. 314 - **varname** : string (default none) - Name of the variable to use. If None, 315 first lvarname is used. 316 - **fillvalue** : object (default '?') - value used for the new extval 317 - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value 318 - **lisfunc** : function (default none) - list of function to apply to indexes before export 319 - **name** : string (default None) - DataArray name. If None, variable name 320 - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values. 321 - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None) 322 - **attrs** : dict (default None) - attributes for the DataArray 323 - **coord** : boolean (default False) - if True, add derivated coords 324 - **kwargs** : parameter for lisfunc 325 326 *Returns* : DataArray ''' 327 option = {'dtype': None} | kwargs 328 if not self.consistent: 329 raise DatasetError("Dataset not consistent") 330 if idxname is None or idxname == []: 331 idxname = self.primaryname 332 ilf = self.full(idxname=idxname, varname=varname, fillvalue=fillvalue, 333 fillextern=fillextern, inplace=False) 334 ilf.setcanonorder() 335 if not varname and len(ilf.lvarname) != 0: 336 varname = ilf.lvarname[0] 337 if not varname in ilf.lname: 338 ivar = -1 339 else: 340 ivar = ilf.lname.index(varname) 341 if isinstance(lisfunc, list) and len(lisfunc) == 1: 342 lisfunc = lisfunc * ilf.lenindex 343 elif isinstance(lisfunc, list) and len(lisfunc) != ilf.lenindex: 344 lisfunc = [None] * ilf.lenindex 345 elif not isinstance(lisfunc, list): 346 funcvar = lisfunc 347 lisfunc = [None] * ilf.lenindex 348 if ivar != -1: 349 lisfunc[ivar] = funcvar 350 lisfuncname = dict(zip(ilf.lname, lisfunc)) 351 coords = ilf._xcoord(idxname, ivar, lisfuncname, coord, **option) 352 dims = idxname 353 if numeric: 354 #lisfunc[ivar] = util.cast 355 fillvalue = math.nan 356 npdtype = 'float' 357 option['dtype'] = 'float' 358 if ivar == -1: 359 data = self.field(list(range(len(ilf)))).to_numpy(npdtype='int')\ 360 .reshape([len(ilf.nindex(name).codec) for name in idxname]) 361 else: 362 data = ilf.lindex[ivar]\ 363 .to_numpy(func=lisfunc[ivar], npdtype=npdtype, **option)\ 364 .reshape([len(ilf.nindex(name).codec) for name in idxname]) 365 if not name and ivar == -1: 366 name = ilf.name 367 elif not name: 368 name = ilf.lname[ivar] 369 if not isinstance(attrs, dict): 370 attrs = {} 371 for nam in ilf.lunicname: 372 attrs[nam] = ilf.nindex(nam).codec[0] 373 if info: 374 attrs |= ilf.indexinfos() 375 return xarray.DataArray(data, coords, dims, attrs=attrs, name=name) 376 377 def voxel(self, idxname=None, varname=None): 378 ''' 379 Plot not null values in a cube with voxels and return indexes values. 380 381 *Parameters* 382 383 - **idxname** : list (default none) - list of idx to be completed. If None, 384 self.primary is used. 385 - **varname** : string (default none) - Name of the variable to use. If None, 386 first lvarname is used. 387 388 *Returns* : **dict of indexes values** 389 ''' 390 if not self.consistent: 391 return None 392 if idxname is None or idxname == []: 393 idxname = self.primaryname 394 if varname is None and self.lvarname: 395 varname = self.lvarname[0] 396 if len(idxname) > 3: 397 raise DatasetError('number of idx > 3') 398 if len(idxname) == 2: 399 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 400 idxname += [' '] 401 elif len(idxname) == 1: 402 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 403 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 404 idxname += [' ', ' '] 405 xar = self.to_xarray(idxname=idxname, varname=varname, fillvalue='?', 406 fillextern=False, lisfunc=util.isNotEqual, tovalue='?') 407 axe = plt.figure().add_subplot(projection='3d') 408 axe.voxels(xar, edgecolor='k') 409 axe.set_xticks(np.arange(self.idxlen[self.idxname.index(xar.dims[0])])) 410 axe.set_yticks(np.arange(self.idxlen[self.idxname.index(xar.dims[1])])) 411 axe.set_zticks(np.arange(self.idxlen[self.idxname.index(xar.dims[2])])) 412 axe.set(xlabel=xar.dims[0][:8], 413 ylabel=xar.dims[1][:8], 414 zlabel=xar.dims[2][:8]) 415 plt.show() 416 self.delindex([' ', ' ']) 417 return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) 418 for i in range(len(xar.dims))} 419 420 def view(self, **kwargs): 421 ''' 422 Generate tabular list to display data. 423 424 *Parameters (kwargs)* 425 426 - **name=listcode** : element (default None) - eg location='ns' 427 - listcode : string with Code for each index (j: json, n: name, s: simple). 428 - name : name of the index 429 - **defcode** : String (default : 'j') - default list code (if 'all' is True) 430 - **all** : Boolean (default : True) - 'defcode apply to all indexes or none 431 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 432 - **header** : Boolean (default : True) - First line with names 433 - **width** : Integer (default None) - Number of characters displayed for each 434 attribute (all if None) 435 - **ifunc** : function (default None) - function to apply to indexes 436 - **tabulate params** : default 'tablefmt': 'simple', 'numalign': 'left', 437 'stralign': 'left', 'floatfmt': '.3f' - See tabulate module 438 - **other kwargs** : parameter for ifunc 439 440 *Returns* : list or html table (tabulate format) ''' 441 # print(kwargs) 442 opttab = {'defcode': 'j', 'all': True, 'lenres': 0, 'header': True} 443 optview = {'tablefmt': 'simple', 'numalign': 'decimal', 444 'stralign': 'left', 'floatfmt': '.2f'} 445 option = opttab | optview | kwargs 446 tab = self._to_tab(**option) 447 width = ({'width': None} | kwargs)['width'] 448 if width: 449 tab = [[(lambda x: x[:width] if isinstance(x, str) else x)(val) 450 for val in lig] for lig in tab] 451 return tabulate(tab, headers='firstrow', **{k: option[k] for k in optview}) 452 453 def vlist(self, *args, func=None, index=-1, **kwargs): 454 ''' 455 Apply a function to an index and return the result. 456 457 *Parameters* 458 459 - **func** : function (default none) - function to apply to extval or extidx 460 - **args, kwargs** : parameters for the function 461 - **index** : integer - index to update (index=-1 for first variable) 462 463 *Returns* : list of func result''' 464 if index == -1 and self.lvar: 465 return self.lvar[0].vlist(func, *args, **kwargs) 466 if index == -1 and self.lenindex == 1: 467 index = 0 468 return self.lindex[index].vlist(func, *args, **kwargs) 469 470 # %%internal 471 """def _optimize_obj(self, idxname, **option2): 472 '''return list object with optimize modecodec''' 473 indexinfos = self.indexinfos() 474 notkeys = True 475 lis = [] 476 if self.iscanonorder(): 477 notkeys = None 478 for idx, iname, inf in zip(self.lindex, idxname, indexinfos): 479 if inf['cat'] == 'unique': 480 lis.append(idx.tostdcodec(full=False).to_obj( 481 name=iname, **option2)) 482 elif inf['cat'] == 'primary': 483 lis.append(idx.to_obj(keys=notkeys, name=iname, **option2)) 484 elif inf['cat'] == 'coupled': 485 lis.append(idx.setkeys(self.lindex[inf['parent']].keys, inplace=False). 486 to_obj(parent=inf['parent'], name=iname, **option2)) 487 elif inf['parent'] == -1: # cat='variable' or 'secondary' 488 if option2['fullvar'] and inf['cat'] == 'variable' and not(inf['child']): 489 opt = option2 | {'modecodec': 'full'} 490 lis.append(idx.to_obj(name=iname, **opt)) 491 elif idx.keys == list(range(len(self))): 492 lis.append(idx.to_obj(name=iname, **option2)) 493 else: 494 lis.append(idx.to_obj(keys=True, name=iname, **option2)) 495 else: # derived 496 if len(self.lindex[inf['parent']].codec) == len(self): 497 lis.append(idx.to_obj(keys=True, name=iname, **option2)) 498 elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): 499 lis.append(idx.to_obj(parent=inf['parent'], 500 name=iname, **option2)) 501 else: # periodic derived 502 keys = idx.derkeys(self.lindex[inf['parent']]) 503 lis.append(idx.to_obj(keys=keys, parent=inf['parent'], 504 name=iname, **option2)) 505 return lis""" 506 507 def _to_tab(self, **kwargs): 508 ''' data preparation (dict of dict) for view or csv export. 509 Representation is included if : 510 - code is definie in the name element of the field 511 - or code is defined in 'defcode' element and 'all' element is True 512 513 *Parameters (kwargs)* 514 515 - **name=listcode** : element (default None) - eg location='ns' 516 - listcode : string with Code for each index (j: json, n: name, s: simple, f: ifunc). 517 - name : name of the index 518 - **defcode** : String (default : 'j') - default list code (if 'all' is True) 519 - **all** : Boolean (default : True) - 'defcode apply to all indexes or none 520 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 521 - **ifunc** : function (default None) - function to apply to indexes 522 - **other kwargs** : parameter for ifunc''' 523 524 option = {'defcode': 'j', 'all': True, 'lenres': 0, 'ifunc': None, 525 'header': True} | kwargs 526 tab = [] 527 reslist = [] 528 diccode = {'j': '', 'n': 'name-', 's': 'smpl-', 'f': 'func-'} 529 if option['header']: 530 for name in self.lname: 531 '''if name in option: 532 for char, code in diccode.items(): 533 if char in option[name]: 534 reslist.append(code + name) 535 elif option['all']: 536 for char, code in diccode.items(): 537 if char in option['defcode']: 538 reslist.append(code + name)''' 539 opt = name if name in option else 'defcode' 540 if opt != 'defcode' or option['all']: 541 for char, code in diccode.items(): 542 if char in option[opt]: 543 reslist.append(code + name) 544 tab.append(reslist) 545 lenres = option['lenres'] 546 if lenres == 0: 547 lenres = len(self) 548 for i in range(min(lenres, len(self))): 549 reslist = [] 550 for name in self.lname: 551 opt = name if name in option else 'defcode' 552 if opt != 'defcode' or option['all']: 553 for char, code in diccode.items(): 554 if char in option[opt]: 555 val = self.nindex(name).values[i] 556 if char == 'j': 557 #reslist.append(util.cast(val, dtype='json')) 558 reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder)) 559 elif char == 'n': 560 reslist.append(self.field.i_to_name(val)) 561 elif char == 's': 562 reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder)) 563 elif char == 'f': 564 reslist.append(util.funclist( 565 val, option['ifunc'], **kwargs)) 566 '''if name in option: 567 for char, code in diccode.items(): 568 if char in option[name]: 569 val = self.nindex(name).values[i] 570 if char == 'j': 571 #reslist.append(util.cast(val, dtype='json')) 572 reslist.append(self.field.s_to_e(val)) 573 elif char == 'n': 574 reslist.append(self.field.i_to_name(val)) 575 elif char == 's': 576 reslist.append( 577 json.dumps(self.field.s_to_e(val))) 578 elif char == 'f': 579 reslist.append(util.funclist( 580 val, option['ifunc'], **kwargs)) 581 elif option['all']: 582 for char, code in diccode.items(): 583 if char in option['defcode']: 584 val = self.nindex(name).values[i] 585 if char == 'j': 586 reslist.append(util.cast(val, dtype='json')) 587 elif char == 'n': 588 reslist.append(util.cast(val, dtype='name')) 589 elif char == 's': 590 reslist.append( 591 util.cast(val, dtype='json', string=True)) 592 elif char == 'f': 593 reslist.append(util.funclist( 594 val, option['ifunc'], **kwargs))''' 595 tab.append(reslist) 596 return tab 597 598 def _xcoord(self, axename, ivar, lisfuncname=None, coord=False, **kwargs): 599 ''' Coords generation for Xarray''' 600 #maxlen = kwargs.get('maxlen', 20) 601 info = self.indexinfos() 602 coords = {} 603 for i in range(self.lenindex): 604 fieldi = info[i] 605 iname = self.lname[i] 606 if fieldi['pparent'] == -1 or i == ivar: 607 continue 608 if isinstance(lisfuncname, dict) and len(lisfuncname) == self.lenindex: 609 funci = lisfuncname[iname] 610 else: 611 funci = None 612 if iname in axename: 613 coords[iname] = self.lindex[i].to_numpy( 614 func=funci, codec=True, **kwargs) 615 if coord: 616 coords[iname+'_row'] = (iname, 617 np.arange(len(coords[iname]))) 618 #coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=util.cast, 619 # codec=True, dtype='str', maxlen=maxlen)) 620 coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=str, codec=True)) 621 else: 622 self.lindex[i].setkeys( 623 self.lindex[fieldi['pparent']].keys) # !!! 624 coords[iname] = (self.lname[fieldi['pparent']], 625 self.lindex[i].to_numpy(func=funci, codec=True, **kwargs)) 626 return coords
this class includes Dataset methods :
50 def json(self, **kwargs): 51 ''' 52 Return json dict, json string or Cbor binary. 53 54 *Parameters (kwargs)* 55 56 - **encoded** : boolean (default False) - choice for return format 57 (string/bytes if True, dict else) 58 - **format** : string (default 'json')- choice for return format (json, cbor) 59 - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder 60 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 61 if 'default' each index has keys, if 'optimize' keys are optimized, 62 if 'dict' dict format is used, if 'nokeys' keys are absent 63 - **name** : boolean (default False) - if False, default index name are not included 64 - **geojson** : boolean (default False) - geojson for LocationValue if True 65 66 *Returns* : string or dict''' 67 return self.to_obj(**kwargs)
Return json dict, json string or Cbor binary.
Parameters (kwargs)
- encoded : boolean (default False) - choice for return format (string/bytes if True, dict else)
- format : string (default 'json')- choice for return format (json, cbor)
- codif : dict (default ES.codeb). Numerical value for string in CBOR encoder
- modecodec : string (default 'optimize') - if 'full', each index is with a full codec if 'default' each index has keys, if 'optimize' keys are optimized, if 'dict' dict format is used, if 'nokeys' keys are absent
- name : boolean (default False) - if False, default index name are not included
- geojson : boolean (default False) - geojson for LocationValue if True
Returns : string or dict
69 def plot(self, varname=None, idxname=None, order=None, line=True, size=5, marker='o', maxlen=20): 70 ''' 71 This function visualize data with line or colormesh. 72 73 *Parameters* 74 75 - **varname** : string (default none) - Name of the variable to use. If None, 76 first lvarname is used. 77 - **line** : Boolean (default True) - Choice line or colormesh. 78 - **order** : list (defaut None) - order of the axes (x, y, hue or col) 79 - **size** : int (defaut 5) - plot size 80 - **marker** : Char (default 'o') - Symbol for each point. 81 - **maxlen** : Integer (default 20) - maximum length for string 82 83 *Returns* 84 85 - **None** ''' 86 if not self.consistent: 87 return None 88 if idxname: 89 idxname = [name for name in idxname if len( 90 self.nindex(name).codec) > 1] 91 #xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=[util.cast],## 92 xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=None, 93 dtype='str', npdtype='str', maxlen=maxlen, coord=True) 94 if not order: 95 order = [0, 1, 2] 96 97 if len(xar.dims) == 1: 98 xar.plot.line(x=xar.dims[0]+'_row', size=size, marker=marker) 99 elif len(xar.dims) == 2 and line: 100 xar.plot.line(x=xar.dims[order[0]] + '_row', 101 xticks=list(xar.coords[xar.dims[0]+'_row'].values), 102 hue=xar.dims[order[1]], size=size, marker=marker) 103 elif len(xar.dims) == 2 and not line: 104 xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row', 105 xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values), 106 yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values), 107 size=size) 108 elif len(xar.dims) == 3 and line: 109 xar.plot.line(x=xar.dims[order[0]] + '_row', col=xar.dims[order[1]], 110 xticks=list( 111 xar.coords[xar.dims[order[0]]+'_row'].values), 112 hue=xar.dims[order[2]], col_wrap=2, size=size, marker=marker) 113 elif len(xar.dims) == 3 and not line: 114 xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row', 115 xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values), 116 yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values), 117 col=xar.dims[order[2]], col_wrap=2, size=size) 118 plt.show() 119 return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) for i in range(len(xar.dims))}
This function visualize data with line or colormesh.
Parameters
- varname : string (default none) - Name of the variable to use. If None, first lvarname is used.
- line : Boolean (default True) - Choice line or colormesh.
- order : list (defaut None) - order of the axes (x, y, hue or col)
- size : int (defaut 5) - plot size
- marker : Char (default 'o') - Symbol for each point.
- maxlen : Integer (default 20) - maximum length for string
Returns
- None
121 def to_csv(self, filename, optcsv={'quoting': csv.QUOTE_NONNUMERIC}, **kwargs): 122 ''' 123 Generate csv file to display data. 124 125 *Parameters* 126 127 - **filename** : string - file name (with path) 128 - **optcsv** : parameter for csv.writer 129 130 *Parameters (kwargs)* 131 132 - **name=listcode** : element (default None) - eg location='ns' 133 - listcode : string with Code for each index (j: json, n: name, s: simple). 134 - name : name of the index 135 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 136 - **header** : Boolean (default : True) - If True, first line with names 137 - **optcsv** : parameter for csv.writer 138 - **ifunc** : function (default None) - function to apply to indexes 139 - **other kwargs** : parameter for ifunc 140 141 *Returns* : size of csv file ''' 142 size = 0 143 if not optcsv: 144 optcsv = {} 145 tab = self._to_tab(**kwargs) 146 with open(filename, 'w', newline='', encoding="utf-8") as csvfile: 147 writer = csv.writer(csvfile, **optcsv) 148 for lign in tab: 149 size += writer.writerow(lign) 150 return size
Generate csv file to display data.
Parameters
- filename : string - file name (with path)
- optcsv : parameter for csv.writer
Parameters (kwargs)
- name=listcode : element (default None) - eg location='ns'
- listcode : string with Code for each index (j: json, n: name, s: simple).
- name : name of the index
- lenres : Integer (default : 0) - Number of raws (all if 0)
- header : Boolean (default : True) - If True, first line with names
- optcsv : parameter for csv.writer
- ifunc : function (default None) - function to apply to indexes
- other kwargs : parameter for ifunc
Returns : size of csv file
152 def to_dataframe(self, info=False, idx=None, fillvalue='?', fillextern=True, 153 lisfunc=None, name=None, numeric=False, npdtype=None, **kwargs): 154 ''' 155 Complete the Object and generate a Pandas DataFrame with the dimension define by idx. 156 157 *Parameters* 158 159 - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray 160 - **idx** : list (default none) - list of idx to be completed. If [], 161 self.primary is used. 162 - **fillvalue** : object (default '?') - value used for the new extval 163 - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value 164 - **lisfunc** : function (default none) - list of function to apply to indexes before export 165 - **name** : string (default None) - DataArray name. If None, variable name 166 - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values. 167 - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None) 168 - **kwargs** : parameter for lisfunc 169 170 *Returns* : pandas.DataFrame ''' 171 if self.consistent: 172 return self.to_xarray(info=info, idx=idx, fillvalue=fillvalue, 173 fillextern=fillextern, lisfunc=lisfunc, name=name, 174 numeric=numeric, npdtype=npdtype, **kwargs 175 ).to_dataframe(name=name) 176 return None
Complete the Object and generate a Pandas DataFrame with the dimension define by idx.
Parameters
- info : boolean (default False) - if True, add _dict attributes to attrs Xarray
- idx : list (default none) - list of idx to be completed. If [], self.primary is used.
- fillvalue : object (default '?') - value used for the new extval
- fillextern : boolean(default True) - if True, fillvalue is converted to internal value
- lisfunc : function (default none) - list of function to apply to indexes before export
- name : string (default None) - DataArray name. If None, variable name
- numeric : Boolean (default False) - Generate a numeric DataArray.Values.
- npdtype : string (default None) - numpy dtype for the DataArray ('object' if None)
- kwargs : parameter for lisfunc
Returns : pandas.DataFrame
178 def to_file(self, filename, **kwargs): 179 '''Generate file to display data. 180 181 *Parameters (kwargs)* 182 183 - **filename** : string - file name (with path) 184 - **kwargs** : see 'to_ntv' parameters 185 186 *Returns* : Integer - file lenght (bytes) ''' 187 option = {'format': 'cbor', 'modecodec': 'optimize'} | kwargs | {'encoded': True} 188 data = self.to_ntv(modecodec=option['modecodec']).to_obj(**option) 189 if option['format'] == 'cbor': 190 size = len(data) 191 with open(filename, 'wb') as file: 192 file.write(data) 193 else: 194 size = len(bytes(data, 'UTF-8')) 195 with open(filename, 'w', newline='', encoding="utf-8") as file: 196 file.write(data) 197 return size
Generate file to display data.
Parameters (kwargs)
- filename : string - file name (with path)
- kwargs : see 'to_ntv' parameters
Returns : Integer - file lenght (bytes)
199 def to_ntv(self, modecodec='optimize', def_type='json', name=False): 200 '''Return a Ntv tab value (whithout name) . 201 202 *Parameters (kwargs)* 203 204 - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec 205 if 'default' each index has keys, if 'optimize' keys are optimized, 206 if 'dict' dict format is used, if 'nokeys' keys are absent 207 - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet 208 - **name** : boolean (default False) - if False, default index name are not included 209 210 211 *Returns* : Ntv object''' 212 idxname = [name or iname != 'i' + str(i) for i, iname in enumerate(self.lname)] 213 if modecodec != 'optimize': 214 lis = [index.to_ntv(modecodec=modecodec, name=iname) 215 for index, iname in zip(self.lindex, idxname)] 216 else: 217 lis = [] 218 indexinfos = self.indexinfos() 219 for idx, inf, iname in zip(self.lindex, indexinfos, idxname): 220 coef = Field.encode_coef(idx.keys) 221 if inf['cat'] == 'unique': 222 lis.append(idx.to_ntv(name=iname)) 223 elif inf['cat'] == 'coupled': 224 idx_coup = idx.setkeys(self.lindex[inf['parent']].keys, inplace=False) 225 lis.append(idx_coup.to_ntv(parent=inf['parent'], name=iname)) 226 elif coef: 227 lis.append(idx.to_ntv(keys=[coef], name=iname)) 228 elif inf['parent'] == -1: # cat='variable' or 'secondary' 229 if idx.keys == list(range(len(self))): 230 lis.append(idx.to_ntv(modecodec='full', name=iname)) 231 else: 232 lis.append(idx.to_ntv(modecodec='default', name=iname)) 233 else: # derived 234 if len(self.lindex[inf['parent']].codec) == len(self): 235 lis.append(idx.to_ntv(modecodec='default', name=iname)) 236 #elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): # periodic derived 237 # lis.append(Field.to_ntv(idx, parent=inf['parent'], name=iname)) 238 else: #derived 239 keys = idx.derkeys(self.lindex[inf['parent']]) 240 lis.append(idx.to_ntv(keys=keys, parent=inf['parent'], name=iname)) 241 return NtvList(lis, None, ntv_type=def_type)
Return a Ntv tab value (whithout name) .
Parameters (kwargs)
- modecodec : string (default 'optimize') - if 'full', each index is with a full codec if 'default' each index has keys, if 'optimize' keys are optimized, if 'dict' dict format is used, if 'nokeys' keys are absent
- def_type : string (default 'json') - default ntv_type for NtvList or NtvSet
- name : boolean (default False) - if False, default index name are not included
Returns : Ntv object
302 def to_xarray(self, info=False, idxname=None, varname=None, fillvalue='?', 303 fillextern=True, lisfunc=None, name=None, numeric=False, 304 npdtype=None, attrs=None, coord=False, **kwargs): 305 ''' 306 Complete the Object and generate a Xarray DataArray with the dimension define by idx. 307 Only the first variable is incuded. 308 309 *Parameters* 310 311 - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray 312 - **idxname** : list (default none) - list of idx to be completed. If None, 313 self.primary is used. 314 - **varname** : string (default none) - Name of the variable to use. If None, 315 first lvarname is used. 316 - **fillvalue** : object (default '?') - value used for the new extval 317 - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value 318 - **lisfunc** : function (default none) - list of function to apply to indexes before export 319 - **name** : string (default None) - DataArray name. If None, variable name 320 - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values. 321 - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None) 322 - **attrs** : dict (default None) - attributes for the DataArray 323 - **coord** : boolean (default False) - if True, add derivated coords 324 - **kwargs** : parameter for lisfunc 325 326 *Returns* : DataArray ''' 327 option = {'dtype': None} | kwargs 328 if not self.consistent: 329 raise DatasetError("Dataset not consistent") 330 if idxname is None or idxname == []: 331 idxname = self.primaryname 332 ilf = self.full(idxname=idxname, varname=varname, fillvalue=fillvalue, 333 fillextern=fillextern, inplace=False) 334 ilf.setcanonorder() 335 if not varname and len(ilf.lvarname) != 0: 336 varname = ilf.lvarname[0] 337 if not varname in ilf.lname: 338 ivar = -1 339 else: 340 ivar = ilf.lname.index(varname) 341 if isinstance(lisfunc, list) and len(lisfunc) == 1: 342 lisfunc = lisfunc * ilf.lenindex 343 elif isinstance(lisfunc, list) and len(lisfunc) != ilf.lenindex: 344 lisfunc = [None] * ilf.lenindex 345 elif not isinstance(lisfunc, list): 346 funcvar = lisfunc 347 lisfunc = [None] * ilf.lenindex 348 if ivar != -1: 349 lisfunc[ivar] = funcvar 350 lisfuncname = dict(zip(ilf.lname, lisfunc)) 351 coords = ilf._xcoord(idxname, ivar, lisfuncname, coord, **option) 352 dims = idxname 353 if numeric: 354 #lisfunc[ivar] = util.cast 355 fillvalue = math.nan 356 npdtype = 'float' 357 option['dtype'] = 'float' 358 if ivar == -1: 359 data = self.field(list(range(len(ilf)))).to_numpy(npdtype='int')\ 360 .reshape([len(ilf.nindex(name).codec) for name in idxname]) 361 else: 362 data = ilf.lindex[ivar]\ 363 .to_numpy(func=lisfunc[ivar], npdtype=npdtype, **option)\ 364 .reshape([len(ilf.nindex(name).codec) for name in idxname]) 365 if not name and ivar == -1: 366 name = ilf.name 367 elif not name: 368 name = ilf.lname[ivar] 369 if not isinstance(attrs, dict): 370 attrs = {} 371 for nam in ilf.lunicname: 372 attrs[nam] = ilf.nindex(nam).codec[0] 373 if info: 374 attrs |= ilf.indexinfos() 375 return xarray.DataArray(data, coords, dims, attrs=attrs, name=name)
Complete the Object and generate a Xarray DataArray with the dimension define by idx. Only the first variable is incuded.
Parameters
- info : boolean (default False) - if True, add _dict attributes to attrs Xarray
- idxname : list (default none) - list of idx to be completed. If None, self.primary is used.
- varname : string (default none) - Name of the variable to use. If None, first lvarname is used.
- fillvalue : object (default '?') - value used for the new extval
- fillextern : boolean(default True) - if True, fillvalue is converted to internal value
- lisfunc : function (default none) - list of function to apply to indexes before export
- name : string (default None) - DataArray name. If None, variable name
- numeric : Boolean (default False) - Generate a numeric DataArray.Values.
- npdtype : string (default None) - numpy dtype for the DataArray ('object' if None)
- attrs : dict (default None) - attributes for the DataArray
- coord : boolean (default False) - if True, add derivated coords
- kwargs : parameter for lisfunc
Returns : DataArray
377 def voxel(self, idxname=None, varname=None): 378 ''' 379 Plot not null values in a cube with voxels and return indexes values. 380 381 *Parameters* 382 383 - **idxname** : list (default none) - list of idx to be completed. If None, 384 self.primary is used. 385 - **varname** : string (default none) - Name of the variable to use. If None, 386 first lvarname is used. 387 388 *Returns* : **dict of indexes values** 389 ''' 390 if not self.consistent: 391 return None 392 if idxname is None or idxname == []: 393 idxname = self.primaryname 394 if varname is None and self.lvarname: 395 varname = self.lvarname[0] 396 if len(idxname) > 3: 397 raise DatasetError('number of idx > 3') 398 if len(idxname) == 2: 399 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 400 idxname += [' '] 401 elif len(idxname) == 1: 402 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 403 self.addindex(self.field('null', ' ', keys=[0]*len(self))) 404 idxname += [' ', ' '] 405 xar = self.to_xarray(idxname=idxname, varname=varname, fillvalue='?', 406 fillextern=False, lisfunc=util.isNotEqual, tovalue='?') 407 axe = plt.figure().add_subplot(projection='3d') 408 axe.voxels(xar, edgecolor='k') 409 axe.set_xticks(np.arange(self.idxlen[self.idxname.index(xar.dims[0])])) 410 axe.set_yticks(np.arange(self.idxlen[self.idxname.index(xar.dims[1])])) 411 axe.set_zticks(np.arange(self.idxlen[self.idxname.index(xar.dims[2])])) 412 axe.set(xlabel=xar.dims[0][:8], 413 ylabel=xar.dims[1][:8], 414 zlabel=xar.dims[2][:8]) 415 plt.show() 416 self.delindex([' ', ' ']) 417 return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) 418 for i in range(len(xar.dims))}
Plot not null values in a cube with voxels and return indexes values.
Parameters
- idxname : list (default none) - list of idx to be completed. If None, self.primary is used.
- varname : string (default none) - Name of the variable to use. If None, first lvarname is used.
Returns : dict of indexes values
420 def view(self, **kwargs): 421 ''' 422 Generate tabular list to display data. 423 424 *Parameters (kwargs)* 425 426 - **name=listcode** : element (default None) - eg location='ns' 427 - listcode : string with Code for each index (j: json, n: name, s: simple). 428 - name : name of the index 429 - **defcode** : String (default : 'j') - default list code (if 'all' is True) 430 - **all** : Boolean (default : True) - 'defcode apply to all indexes or none 431 - **lenres** : Integer (default : 0) - Number of raws (all if 0) 432 - **header** : Boolean (default : True) - First line with names 433 - **width** : Integer (default None) - Number of characters displayed for each 434 attribute (all if None) 435 - **ifunc** : function (default None) - function to apply to indexes 436 - **tabulate params** : default 'tablefmt': 'simple', 'numalign': 'left', 437 'stralign': 'left', 'floatfmt': '.3f' - See tabulate module 438 - **other kwargs** : parameter for ifunc 439 440 *Returns* : list or html table (tabulate format) ''' 441 # print(kwargs) 442 opttab = {'defcode': 'j', 'all': True, 'lenres': 0, 'header': True} 443 optview = {'tablefmt': 'simple', 'numalign': 'decimal', 444 'stralign': 'left', 'floatfmt': '.2f'} 445 option = opttab | optview | kwargs 446 tab = self._to_tab(**option) 447 width = ({'width': None} | kwargs)['width'] 448 if width: 449 tab = [[(lambda x: x[:width] if isinstance(x, str) else x)(val) 450 for val in lig] for lig in tab] 451 return tabulate(tab, headers='firstrow', **{k: option[k] for k in optview})
Generate tabular list to display data.
Parameters (kwargs)
- name=listcode : element (default None) - eg location='ns'
- listcode : string with Code for each index (j: json, n: name, s: simple).
- name : name of the index
- defcode : String (default : 'j') - default list code (if 'all' is True)
- all : Boolean (default : True) - 'defcode apply to all indexes or none
- lenres : Integer (default : 0) - Number of raws (all if 0)
- header : Boolean (default : True) - First line with names
- width : Integer (default None) - Number of characters displayed for each attribute (all if None)
- ifunc : function (default None) - function to apply to indexes
- tabulate params : default 'tablefmt': 'simple', 'numalign': 'left', 'stralign': 'left', 'floatfmt': '.3f' - See tabulate module
- other kwargs : parameter for ifunc
Returns : list or html table (tabulate format)
453 def vlist(self, *args, func=None, index=-1, **kwargs): 454 ''' 455 Apply a function to an index and return the result. 456 457 *Parameters* 458 459 - **func** : function (default none) - function to apply to extval or extidx 460 - **args, kwargs** : parameters for the function 461 - **index** : integer - index to update (index=-1 for first variable) 462 463 *Returns* : list of func result''' 464 if index == -1 and self.lvar: 465 return self.lvar[0].vlist(func, *args, **kwargs) 466 if index == -1 and self.lenindex == 1: 467 index = 0 468 return self.lindex[index].vlist(func, *args, **kwargs)
Apply a function to an index and return the result.
Parameters
- func : function (default none) - function to apply to extval or extidx
- args, kwargs : parameters for the function
- index : integer - index to update (index=-1 for first variable)
Returns : list of func result