python.observation.field_interface

Created on Sun Oct 2 22:24:59 2022

@author: philippe@loco-labs.io

The python.observation.field_interface module contains the FieldInterface class (python.observation.field.Field 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.field_interface` module contains the `FieldInterface` class
  8(`python.observation.field.Field` methods).
  9"""
 10# %% declarations
 11import json
 12import datetime
 13import numpy as np
 14import pandas as pd
 15import cbor2
 16
 17from observation.esconstante import ES
 18from observation.util import util, identity
 19from json_ntv.ntv import Ntv, NtvSingle, NtvList
 20
 21
 22class CborDecoder(json.JSONDecoder):
 23    ''' Cbor extension for integer keys (codification keys)'''
 24
 25    def __init__(self):
 26        json.JSONDecoder.__init__(self, object_hook=self.codecbor)
 27
 28    def codecbor(self, dic):
 29        dic2 = {}
 30        for k, v in dic.items():
 31            try:
 32                k2 = int(k)
 33            except:
 34                k2 = k
 35            dic2[k2] = v
 36        return dic2
 37
 38
 39class FieldError(Exception):
 40    ''' Field Exception'''
 41    # pass
 42
 43
 44class FieldEncoder(json.JSONEncoder):
 45    """new json encoder for Field and Dataset"""
 46
 47    def default(self, o):
 48        if isinstance(o, datetime.datetime):
 49            return o.isoformat()
 50        option = {'encoded': False, 'format': 'json'}
 51        if o.__class__.__name__ in ('Dataset', 'TimeSlot', 'Ndataset', 'Sdataset'):
 52            return o.json(**option)
 53        #if issubclass(o.__class__, ESValue):
 54        #    return o.json(**option)
 55        try:
 56            return o.to_json(**option)
 57        except:
 58            try:
 59                return o.__to_json__()
 60            except:
 61                return json.JSONEncoder.default(self, o)
 62
 63
 64class FieldInterface:
 65    '''this class includes Field methods :
 66
 67    - `FieldInterface.json`
 68    - `FieldInterface.to_obj`
 69    - `FieldInterface.to_dict_obj`
 70    - `FieldInterface.to_numpy`
 71    - `FieldInterface.to_pandas`
 72    - `FieldInterface.vlist`
 73    - `FieldInterface.vName`
 74    - `FieldInterface.vSimple`
 75    '''
 76
 77
 78    @classmethod 
 79    def decode_ntv(cls, field, fast=False):
 80        '''Generate a tuple data from a Ntv value(bytes, string, json, Ntv object)
 81
 82        *Parameters*
 83
 84        - **field** : bytes, string json or Ntv object to convert
 85        - **format** : string (default 'json') - format to convert ntv_value
 86        - **fast**: boolean (default False) - if True, codec is created without 
 87        conversion, else codec is created with json structure
 88
 89        *Returns* 
 90
 91        - **tuple** : name, dtype, codec, parent, keys, coef, leng
 92            name (None or string): name of the Field
 93            dtype (None or string): type of data
 94            codec (list): list of Field codec values
 95            parent (None or int): Field parent or None
 96            keys (None or list): Field keys
 97            coef (None or int): coef if primary Field else None
 98            leng (int): length of the Field
 99        '''
100        ntv = Ntv.obj(field)
101        typ = ntv.type_str if ntv.ntv_type else None
102        nam = ntv.name
103        val = ntv.val
104        if isinstance(ntv, NtvSingle):
105            return (nam, typ, [cls.s_to_i(val, fast)], None, None, None, 1)
106        if len(ntv) == 0:
107            return (nam, typ, cls.n_to_i(val, fast), None, None, None, 0)
108        if len(ntv) > 3 or isinstance(ntv[0], NtvSingle):
109            return (nam, typ, cls.n_to_i(val, fast), None, None, None, len(ntv))
110        if len(ntv) == 1:
111            return (nam, typ, [cls.s_to_i(val, fast)[0]], None, None, None, 1)
112
113        ntvc = ntv[0]
114        leng = max(len(ind) for ind in ntv)
115        typc = ntvc.type_str if ntvc.ntv_type else None
116        valc = ntvc.val
117        if len(ntv) == 3 and isinstance(ntv[1], NtvSingle) and \
118            isinstance(ntv[1].val, (int, str)) and not isinstance(ntv[2], NtvSingle) and \
119            isinstance(ntv[2][0].val, int):
120            return (nam, typc, cls.n_to_i(valc, fast), ntv[1].val, ntv[2].to_obj(), None, leng)
121        if len(ntv) == 2 and len(ntv[1]) == 1 and isinstance(ntv[1].val, (int, str)):
122            return (nam, typc, cls.n_to_i(valc, fast), ntv[1].val, None, None, leng) 
123        if len(ntv) == 2 and len(ntv[1]) == 1 and isinstance(ntv[1].val, list):
124            leng = leng * ntv[1][0].val
125            return (nam, typc, cls.n_to_i(valc, fast), None, None, ntv[1][0].val, leng) 
126        if len(ntv) == 2 and len(ntv[1]) > 1  and isinstance(ntv[1][0].val, int):
127            return (nam, typc, cls.n_to_i(valc, fast), None, ntv[1].to_obj(), None, leng)
128        return (nam, typ, cls.n_to_i(val, fast), None, None, None, len(ntv))
129
130    @staticmethod 
131    def encode_coef(lis):
132        '''Generate a repetition coefficient for periodic list'''
133        if len(lis) < 2:
134            return 0
135        coef = 1
136        while coef != len(lis):
137            if lis[coef-1] != lis[coef]:
138                break
139            coef += 1
140        #print('coef : ', coef)
141        '''coef = 0
142        for i in range(1,len(lis)):
143            coef = i
144            if lis[i-1] != lis[i]:
145                break'''
146        if (not len(lis) % (coef * (max(lis) + 1)) and 
147            lis == FieldInterface.keysfromcoef(coef, max(lis) + 1, len(lis))):
148            return coef
149        return 0
150
151    @staticmethod 
152    def keysfromcoef(coef, period, leng=None):
153        ''' return a list of keys with periodic structure'''
154        if not leng:
155            leng = coef * period
156        return None if not coef or not period else [ (ikey % (coef * period)) // coef 
157                                                    for ikey in range(leng)]
158    
159    def to_dict_obj(self, typevalue=None, simpleval=False, modecodec='optimize', **kwargs):
160        '''deprecated method'''
161        option = {'encoded': False, 'format': 'json', 'untyped': False,
162                  'codif': {}, 'geojson': False} | kwargs
163        dic = {}
164        if self.typevalue:
165            dic['type'] = self.typevalue
166        ds = pd.Series(range(len(self.keys)), index=self.keys, dtype='int64')
167        dic['value'] = [{'record': ds[i].tolist(),
168                         'codec': util.json(cod, encoded=False, typevalue=None,
169                                            simpleval=simpleval, modecodec=modecodec,
170                                            untyped=option['untyped'], datetime=False,
171                                            geojson=option['geojson'])}
172                        for i, cod in enumerate(self.codec)]
173        return {self.name: dic}
174
175    def to_numpy(self, func=None, codec=False, npdtype=None, **kwargs):
176        '''
177        Transform Field in a Numpy array.
178
179        *Parameters*
180
181        - **func** : function (default None) - function to apply for each value of the Field.
182        If func is the 'index' string, values are replaced by raw values.
183        - **npdtype** : string (default None) - numpy dtype for the Array ('object' if None)
184        - **kwargs** : parameters to apply to the func function
185
186        *Returns* : Numpy Array'''
187        return self.to_pandas(func=func, codec=codec, npdtype=npdtype, numpy=True, **kwargs)
188
189    def to_ntv(self, modecodec='optimize', codecval=False, def_type=None, 
190               keys=None, parent=None, name=True, coef=None):
191        '''Return a Ntv field value
192
193        *Parameters (kwargs)*
194
195        - **modecodec** : string (default 'optimize') - if 'full', index is with a full codec
196        if 'default' index has keys, if 'optimize' keys are optimized, 
197        - **codecval** : boolean (default False) - if True, only list of codec values is included
198        - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet
199        - **name** : boolean (default False) - if False, default index name are not included
200        - **keys** : list (default None) - used only with 'optimize' mode
201        - **parent** : int or str (default None) - used only with 'optimize' mode
202
203        *Returns* : Ntv object'''
204        leng = len(self)
205        codec = self.i_to_n(self.codec)
206        def_type = codec[0].ntv_type if not def_type and codec else def_type
207        idxname = None if self.name == '$default' or not name else self.name       
208        '''if len(self.codec) == 1:
209            return NtvSingle(self.codec[0].ntv_value, idxname, self.codec[0].ntv_type)
210        if codecval:
211            return NtvList(self.codec, idxname, ntv_type=def_type)
212        if len(self.codec) == leng or modecodec == 'full':
213            return NtvList(self.values, idxname, ntv_type=def_type)
214        if modecodec == 'default':
215            return NtvList([NtvList(self.codec, ntv_type=def_type), 
216                            NtvList(self.keys, ntv_type='json')], idxname, ntv_type='json')
217        if modecodec == 'optimize':
218            ntv_value = [NtvList(self.codec, ntv_type=def_type)]'''
219        if leng == 1 or len(codec) == 1 and modecodec != 'full':
220            return NtvSingle(codec[0].ntv_value, idxname, codec[0].ntv_type)
221        if codecval or modecodec == 'nokeys':
222            return NtvList(codec, idxname, ntv_type=def_type)
223        if len(codec) == leng or modecodec == 'full':
224            #if (len(codec) == leng and not self.keys) or modecodec == 'full':
225            #return NtvList(self.l_to_e(self.values), idxname, ntv_type=def_type)
226            return NtvList(self.values, idxname, ntv_type=def_type)
227        if modecodec == 'default':
228            return NtvList([NtvList(codec, ntv_type=def_type), 
229                            NtvList(self.keys, ntv_type='json')], idxname, ntv_type='json')
230        if coef:
231            return NtvList([NtvList(codec, ntv_type=def_type),
232                         NtvList([coef], ntv_type='json')], idxname, ntv_type='json')                        
233        if modecodec == 'optimize':
234            ntv_value = [NtvList(codec, ntv_type=def_type)]
235            if not parent is None:
236                ntv_value.append(NtvSingle(parent, ntv_type='json'))
237            if keys:
238                ntv_value.append(NtvList(keys, ntv_type='json'))    
239            elif parent is None:
240                ntv_value.append(NtvList(self.keys, ntv_type='json'))
241            return NtvList(ntv_value, idxname, ntv_type='json')                
242
243    def to_pandas(self, func=None, codec=False, npdtype=None,
244                  series=True, index=True, numpy=False, **kwargs):
245        '''
246        Transform Field in a Pandas Series, Pandas DataFrame or Numpy array.
247
248        *Parameters*
249
250        - **func** : function (default None) - function to apply for each value of the Field.
251        If func is the 'index' string, values are replaced by raw values.
252        - **npdtype** : string (default None) - numpy dtype for the Array ('object' if None)
253        - **series** : boolean (default True) - if True, return a Series. 
254        If False return a DataFrame
255        - **index** : boolean (default True) - if True, index is keys.
256        - **numpy** : boolean (default False) - if True, return a Numpy array.
257        - **kwargs** : parameters to apply to the func function
258
259        *Returns* : Pandas Series, Pandas DataFrame, Numpy Array'''
260        if len(self) == 0:
261            raise FieldError("Dataset is empty")
262        if npdtype:
263            npdtype = np.dtype(npdtype)
264        else:
265            npdtype = 'object'
266        if func is None:
267            func = identity
268        if func == 'index':
269            return np.array(list(range(len(self))))
270        if not codec:
271            values = util.funclist(self.values, func, **kwargs)
272        else:
273            values = util.funclist(self._codec, func, **kwargs)
274        npdtype1 = npdtype
275        if isinstance(values[0], (datetime.datetime)):
276            npdtype1 = np.datetime64
277        # else:
278        #    npdtype=None
279        pdindex = None
280        if index:
281            pdindex = self._keys
282        try:
283            if numpy:
284                return np.array(values, dtype=npdtype1)
285            if series:
286                return pd.Series(values, dtype=npdtype1,
287                                 index=pdindex, name=self.name)
288            return pd.DataFrame(pd.Series(values, dtype=npdtype1,
289                                          index=pdindex, name=self.name))
290        except:
291            if numpy:
292                return np.array(values, dtype=npdtype)
293            if series:
294                return pd.Series(values, dtype=npdtype,
295                                 index=pdindex, name=self.name)
296            return pd.DataFrame(pd.Series(values, dtype=npdtype,
297                                          index=pdindex, name=self.name))
298
299    def vlist(self, func, *args, extern=True, **kwargs):
300        '''
301        Apply a function to values and return the result.
302
303        *Parameters*
304
305        - **func** : function - function to apply to values
306        - **args, kwargs** : parameters for the function
307        - **extern** : if True, the function is apply to external values, else internal
308
309        *Returns* : list of func result'''
310        if extern:
311            return util.funclist(self.val, func, *args, **kwargs)
312        return util.funclist(self.values, func, *args, **kwargs)
313
314    def vName(self, default=ES.nullName, maxlen=None):
315        '''
316        Return the list of name for ESValue data .
317
318        *Parameters*
319
320        - **default** : value return if no name is available
321        - **maxlen** : integer (default None) - max length of name
322
323        *Returns* : list of name founded'''
324        #return [util.cast(val, dtype='name', default=default, maxlen=maxlen) for val in self.values]
325        return [self.i_to_name(val) for val in self.values]
326
327    """def vSimple(self, string=False):
328        '''
329        Apply a vSimple function to values and return the result.
330
331        *Parameters*
332
333        - **string** : boolean(default False) - if True the values returned are string
334
335        *Returns* : list of vSimple values (string or not)'''
336        if string:
337            return json.dumps([util.cast(val, 'simple', string=string) for val in self.values],
338                              cls=ESValueEncoder)
339        return [util.cast(val, 'simple', string=string) for val in self.values]"""
class CborDecoder(json.decoder.JSONDecoder):
23class CborDecoder(json.JSONDecoder):
24    ''' Cbor extension for integer keys (codification keys)'''
25
26    def __init__(self):
27        json.JSONDecoder.__init__(self, object_hook=self.codecbor)
28
29    def codecbor(self, dic):
30        dic2 = {}
31        for k, v in dic.items():
32            try:
33                k2 = int(k)
34            except:
35                k2 = k
36            dic2[k2] = v
37        return dic2

Cbor extension for integer keys (codification keys)

CborDecoder()
26    def __init__(self):
27        json.JSONDecoder.__init__(self, object_hook=self.codecbor)

object_hook, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given dict. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting).

object_pairs_hook, if specified will be called with the result of every JSON object decoded with an ordered list of pairs. The return value of object_pairs_hook will be used instead of the dict. This feature can be used to implement custom decoders. If object_hook is also defined, the object_pairs_hook takes priority.

parse_float, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal).

parse_int, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float).

parse_constant, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered.

If strict is false (true is the default), then control characters will be allowed inside strings. Control characters in this context are those with character codes in the 0-31 range, including '\t' (tab), '\n', '\r' and '\0'.

def codecbor(self, dic):
29    def codecbor(self, dic):
30        dic2 = {}
31        for k, v in dic.items():
32            try:
33                k2 = int(k)
34            except:
35                k2 = k
36            dic2[k2] = v
37        return dic2
Inherited Members
json.decoder.JSONDecoder
object_hook
parse_float
parse_int
parse_constant
strict
object_pairs_hook
parse_object
parse_array
parse_string
memo
scan_once
decode
raw_decode
class FieldError(builtins.Exception):
40class FieldError(Exception):
41    ''' Field Exception'''
42    # pass

Field Exception

Inherited Members
builtins.Exception
Exception
builtins.BaseException
with_traceback
args
class FieldEncoder(json.encoder.JSONEncoder):
45class FieldEncoder(json.JSONEncoder):
46    """new json encoder for Field and Dataset"""
47
48    def default(self, o):
49        if isinstance(o, datetime.datetime):
50            return o.isoformat()
51        option = {'encoded': False, 'format': 'json'}
52        if o.__class__.__name__ in ('Dataset', 'TimeSlot', 'Ndataset', 'Sdataset'):
53            return o.json(**option)
54        #if issubclass(o.__class__, ESValue):
55        #    return o.json(**option)
56        try:
57            return o.to_json(**option)
58        except:
59            try:
60                return o.__to_json__()
61            except:
62                return json.JSONEncoder.default(self, o)

new json encoder for Field and Dataset

def default(self, o):
48    def default(self, o):
49        if isinstance(o, datetime.datetime):
50            return o.isoformat()
51        option = {'encoded': False, 'format': 'json'}
52        if o.__class__.__name__ in ('Dataset', 'TimeSlot', 'Ndataset', 'Sdataset'):
53            return o.json(**option)
54        #if issubclass(o.__class__, ESValue):
55        #    return o.json(**option)
56        try:
57            return o.to_json(**option)
58        except:
59            try:
60                return o.__to_json__()
61            except:
62                return json.JSONEncoder.default(self, o)

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this::

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)
Inherited Members
json.encoder.JSONEncoder
JSONEncoder
item_separator
key_separator
skipkeys
ensure_ascii
check_circular
allow_nan
sort_keys
indent
encode
iterencode
class FieldInterface:
 65class FieldInterface:
 66    '''this class includes Field methods :
 67
 68    - `FieldInterface.json`
 69    - `FieldInterface.to_obj`
 70    - `FieldInterface.to_dict_obj`
 71    - `FieldInterface.to_numpy`
 72    - `FieldInterface.to_pandas`
 73    - `FieldInterface.vlist`
 74    - `FieldInterface.vName`
 75    - `FieldInterface.vSimple`
 76    '''
 77
 78
 79    @classmethod 
 80    def decode_ntv(cls, field, fast=False):
 81        '''Generate a tuple data from a Ntv value(bytes, string, json, Ntv object)
 82
 83        *Parameters*
 84
 85        - **field** : bytes, string json or Ntv object to convert
 86        - **format** : string (default 'json') - format to convert ntv_value
 87        - **fast**: boolean (default False) - if True, codec is created without 
 88        conversion, else codec is created with json structure
 89
 90        *Returns* 
 91
 92        - **tuple** : name, dtype, codec, parent, keys, coef, leng
 93            name (None or string): name of the Field
 94            dtype (None or string): type of data
 95            codec (list): list of Field codec values
 96            parent (None or int): Field parent or None
 97            keys (None or list): Field keys
 98            coef (None or int): coef if primary Field else None
 99            leng (int): length of the Field
100        '''
101        ntv = Ntv.obj(field)
102        typ = ntv.type_str if ntv.ntv_type else None
103        nam = ntv.name
104        val = ntv.val
105        if isinstance(ntv, NtvSingle):
106            return (nam, typ, [cls.s_to_i(val, fast)], None, None, None, 1)
107        if len(ntv) == 0:
108            return (nam, typ, cls.n_to_i(val, fast), None, None, None, 0)
109        if len(ntv) > 3 or isinstance(ntv[0], NtvSingle):
110            return (nam, typ, cls.n_to_i(val, fast), None, None, None, len(ntv))
111        if len(ntv) == 1:
112            return (nam, typ, [cls.s_to_i(val, fast)[0]], None, None, None, 1)
113
114        ntvc = ntv[0]
115        leng = max(len(ind) for ind in ntv)
116        typc = ntvc.type_str if ntvc.ntv_type else None
117        valc = ntvc.val
118        if len(ntv) == 3 and isinstance(ntv[1], NtvSingle) and \
119            isinstance(ntv[1].val, (int, str)) and not isinstance(ntv[2], NtvSingle) and \
120            isinstance(ntv[2][0].val, int):
121            return (nam, typc, cls.n_to_i(valc, fast), ntv[1].val, ntv[2].to_obj(), None, leng)
122        if len(ntv) == 2 and len(ntv[1]) == 1 and isinstance(ntv[1].val, (int, str)):
123            return (nam, typc, cls.n_to_i(valc, fast), ntv[1].val, None, None, leng) 
124        if len(ntv) == 2 and len(ntv[1]) == 1 and isinstance(ntv[1].val, list):
125            leng = leng * ntv[1][0].val
126            return (nam, typc, cls.n_to_i(valc, fast), None, None, ntv[1][0].val, leng) 
127        if len(ntv) == 2 and len(ntv[1]) > 1  and isinstance(ntv[1][0].val, int):
128            return (nam, typc, cls.n_to_i(valc, fast), None, ntv[1].to_obj(), None, leng)
129        return (nam, typ, cls.n_to_i(val, fast), None, None, None, len(ntv))
130
131    @staticmethod 
132    def encode_coef(lis):
133        '''Generate a repetition coefficient for periodic list'''
134        if len(lis) < 2:
135            return 0
136        coef = 1
137        while coef != len(lis):
138            if lis[coef-1] != lis[coef]:
139                break
140            coef += 1
141        #print('coef : ', coef)
142        '''coef = 0
143        for i in range(1,len(lis)):
144            coef = i
145            if lis[i-1] != lis[i]:
146                break'''
147        if (not len(lis) % (coef * (max(lis) + 1)) and 
148            lis == FieldInterface.keysfromcoef(coef, max(lis) + 1, len(lis))):
149            return coef
150        return 0
151
152    @staticmethod 
153    def keysfromcoef(coef, period, leng=None):
154        ''' return a list of keys with periodic structure'''
155        if not leng:
156            leng = coef * period
157        return None if not coef or not period else [ (ikey % (coef * period)) // coef 
158                                                    for ikey in range(leng)]
159    
160    def to_dict_obj(self, typevalue=None, simpleval=False, modecodec='optimize', **kwargs):
161        '''deprecated method'''
162        option = {'encoded': False, 'format': 'json', 'untyped': False,
163                  'codif': {}, 'geojson': False} | kwargs
164        dic = {}
165        if self.typevalue:
166            dic['type'] = self.typevalue
167        ds = pd.Series(range(len(self.keys)), index=self.keys, dtype='int64')
168        dic['value'] = [{'record': ds[i].tolist(),
169                         'codec': util.json(cod, encoded=False, typevalue=None,
170                                            simpleval=simpleval, modecodec=modecodec,
171                                            untyped=option['untyped'], datetime=False,
172                                            geojson=option['geojson'])}
173                        for i, cod in enumerate(self.codec)]
174        return {self.name: dic}
175
176    def to_numpy(self, func=None, codec=False, npdtype=None, **kwargs):
177        '''
178        Transform Field in a Numpy array.
179
180        *Parameters*
181
182        - **func** : function (default None) - function to apply for each value of the Field.
183        If func is the 'index' string, values are replaced by raw values.
184        - **npdtype** : string (default None) - numpy dtype for the Array ('object' if None)
185        - **kwargs** : parameters to apply to the func function
186
187        *Returns* : Numpy Array'''
188        return self.to_pandas(func=func, codec=codec, npdtype=npdtype, numpy=True, **kwargs)
189
190    def to_ntv(self, modecodec='optimize', codecval=False, def_type=None, 
191               keys=None, parent=None, name=True, coef=None):
192        '''Return a Ntv field value
193
194        *Parameters (kwargs)*
195
196        - **modecodec** : string (default 'optimize') - if 'full', index is with a full codec
197        if 'default' index has keys, if 'optimize' keys are optimized, 
198        - **codecval** : boolean (default False) - if True, only list of codec values is included
199        - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet
200        - **name** : boolean (default False) - if False, default index name are not included
201        - **keys** : list (default None) - used only with 'optimize' mode
202        - **parent** : int or str (default None) - used only with 'optimize' mode
203
204        *Returns* : Ntv object'''
205        leng = len(self)
206        codec = self.i_to_n(self.codec)
207        def_type = codec[0].ntv_type if not def_type and codec else def_type
208        idxname = None if self.name == '$default' or not name else self.name       
209        '''if len(self.codec) == 1:
210            return NtvSingle(self.codec[0].ntv_value, idxname, self.codec[0].ntv_type)
211        if codecval:
212            return NtvList(self.codec, idxname, ntv_type=def_type)
213        if len(self.codec) == leng or modecodec == 'full':
214            return NtvList(self.values, idxname, ntv_type=def_type)
215        if modecodec == 'default':
216            return NtvList([NtvList(self.codec, ntv_type=def_type), 
217                            NtvList(self.keys, ntv_type='json')], idxname, ntv_type='json')
218        if modecodec == 'optimize':
219            ntv_value = [NtvList(self.codec, ntv_type=def_type)]'''
220        if leng == 1 or len(codec) == 1 and modecodec != 'full':
221            return NtvSingle(codec[0].ntv_value, idxname, codec[0].ntv_type)
222        if codecval or modecodec == 'nokeys':
223            return NtvList(codec, idxname, ntv_type=def_type)
224        if len(codec) == leng or modecodec == 'full':
225            #if (len(codec) == leng and not self.keys) or modecodec == 'full':
226            #return NtvList(self.l_to_e(self.values), idxname, ntv_type=def_type)
227            return NtvList(self.values, idxname, ntv_type=def_type)
228        if modecodec == 'default':
229            return NtvList([NtvList(codec, ntv_type=def_type), 
230                            NtvList(self.keys, ntv_type='json')], idxname, ntv_type='json')
231        if coef:
232            return NtvList([NtvList(codec, ntv_type=def_type),
233                         NtvList([coef], ntv_type='json')], idxname, ntv_type='json')                        
234        if modecodec == 'optimize':
235            ntv_value = [NtvList(codec, ntv_type=def_type)]
236            if not parent is None:
237                ntv_value.append(NtvSingle(parent, ntv_type='json'))
238            if keys:
239                ntv_value.append(NtvList(keys, ntv_type='json'))    
240            elif parent is None:
241                ntv_value.append(NtvList(self.keys, ntv_type='json'))
242            return NtvList(ntv_value, idxname, ntv_type='json')                
243
244    def to_pandas(self, func=None, codec=False, npdtype=None,
245                  series=True, index=True, numpy=False, **kwargs):
246        '''
247        Transform Field in a Pandas Series, Pandas DataFrame or Numpy array.
248
249        *Parameters*
250
251        - **func** : function (default None) - function to apply for each value of the Field.
252        If func is the 'index' string, values are replaced by raw values.
253        - **npdtype** : string (default None) - numpy dtype for the Array ('object' if None)
254        - **series** : boolean (default True) - if True, return a Series. 
255        If False return a DataFrame
256        - **index** : boolean (default True) - if True, index is keys.
257        - **numpy** : boolean (default False) - if True, return a Numpy array.
258        - **kwargs** : parameters to apply to the func function
259
260        *Returns* : Pandas Series, Pandas DataFrame, Numpy Array'''
261        if len(self) == 0:
262            raise FieldError("Dataset is empty")
263        if npdtype:
264            npdtype = np.dtype(npdtype)
265        else:
266            npdtype = 'object'
267        if func is None:
268            func = identity
269        if func == 'index':
270            return np.array(list(range(len(self))))
271        if not codec:
272            values = util.funclist(self.values, func, **kwargs)
273        else:
274            values = util.funclist(self._codec, func, **kwargs)
275        npdtype1 = npdtype
276        if isinstance(values[0], (datetime.datetime)):
277            npdtype1 = np.datetime64
278        # else:
279        #    npdtype=None
280        pdindex = None
281        if index:
282            pdindex = self._keys
283        try:
284            if numpy:
285                return np.array(values, dtype=npdtype1)
286            if series:
287                return pd.Series(values, dtype=npdtype1,
288                                 index=pdindex, name=self.name)
289            return pd.DataFrame(pd.Series(values, dtype=npdtype1,
290                                          index=pdindex, name=self.name))
291        except:
292            if numpy:
293                return np.array(values, dtype=npdtype)
294            if series:
295                return pd.Series(values, dtype=npdtype,
296                                 index=pdindex, name=self.name)
297            return pd.DataFrame(pd.Series(values, dtype=npdtype,
298                                          index=pdindex, name=self.name))
299
300    def vlist(self, func, *args, extern=True, **kwargs):
301        '''
302        Apply a function to values and return the result.
303
304        *Parameters*
305
306        - **func** : function - function to apply to values
307        - **args, kwargs** : parameters for the function
308        - **extern** : if True, the function is apply to external values, else internal
309
310        *Returns* : list of func result'''
311        if extern:
312            return util.funclist(self.val, func, *args, **kwargs)
313        return util.funclist(self.values, func, *args, **kwargs)
314
315    def vName(self, default=ES.nullName, maxlen=None):
316        '''
317        Return the list of name for ESValue data .
318
319        *Parameters*
320
321        - **default** : value return if no name is available
322        - **maxlen** : integer (default None) - max length of name
323
324        *Returns* : list of name founded'''
325        #return [util.cast(val, dtype='name', default=default, maxlen=maxlen) for val in self.values]
326        return [self.i_to_name(val) for val in self.values]
327
328    """def vSimple(self, string=False):
329        '''
330        Apply a vSimple function to values and return the result.
331
332        *Parameters*
333
334        - **string** : boolean(default False) - if True the values returned are string
335
336        *Returns* : list of vSimple values (string or not)'''
337        if string:
338            return json.dumps([util.cast(val, 'simple', string=string) for val in self.values],
339                              cls=ESValueEncoder)
340        return [util.cast(val, 'simple', string=string) for val in self.values]"""

this class includes Field methods :

@classmethod
def decode_ntv(cls, field, fast=False):
 79    @classmethod 
 80    def decode_ntv(cls, field, fast=False):
 81        '''Generate a tuple data from a Ntv value(bytes, string, json, Ntv object)
 82
 83        *Parameters*
 84
 85        - **field** : bytes, string json or Ntv object to convert
 86        - **format** : string (default 'json') - format to convert ntv_value
 87        - **fast**: boolean (default False) - if True, codec is created without 
 88        conversion, else codec is created with json structure
 89
 90        *Returns* 
 91
 92        - **tuple** : name, dtype, codec, parent, keys, coef, leng
 93            name (None or string): name of the Field
 94            dtype (None or string): type of data
 95            codec (list): list of Field codec values
 96            parent (None or int): Field parent or None
 97            keys (None or list): Field keys
 98            coef (None or int): coef if primary Field else None
 99            leng (int): length of the Field
100        '''
101        ntv = Ntv.obj(field)
102        typ = ntv.type_str if ntv.ntv_type else None
103        nam = ntv.name
104        val = ntv.val
105        if isinstance(ntv, NtvSingle):
106            return (nam, typ, [cls.s_to_i(val, fast)], None, None, None, 1)
107        if len(ntv) == 0:
108            return (nam, typ, cls.n_to_i(val, fast), None, None, None, 0)
109        if len(ntv) > 3 or isinstance(ntv[0], NtvSingle):
110            return (nam, typ, cls.n_to_i(val, fast), None, None, None, len(ntv))
111        if len(ntv) == 1:
112            return (nam, typ, [cls.s_to_i(val, fast)[0]], None, None, None, 1)
113
114        ntvc = ntv[0]
115        leng = max(len(ind) for ind in ntv)
116        typc = ntvc.type_str if ntvc.ntv_type else None
117        valc = ntvc.val
118        if len(ntv) == 3 and isinstance(ntv[1], NtvSingle) and \
119            isinstance(ntv[1].val, (int, str)) and not isinstance(ntv[2], NtvSingle) and \
120            isinstance(ntv[2][0].val, int):
121            return (nam, typc, cls.n_to_i(valc, fast), ntv[1].val, ntv[2].to_obj(), None, leng)
122        if len(ntv) == 2 and len(ntv[1]) == 1 and isinstance(ntv[1].val, (int, str)):
123            return (nam, typc, cls.n_to_i(valc, fast), ntv[1].val, None, None, leng) 
124        if len(ntv) == 2 and len(ntv[1]) == 1 and isinstance(ntv[1].val, list):
125            leng = leng * ntv[1][0].val
126            return (nam, typc, cls.n_to_i(valc, fast), None, None, ntv[1][0].val, leng) 
127        if len(ntv) == 2 and len(ntv[1]) > 1  and isinstance(ntv[1][0].val, int):
128            return (nam, typc, cls.n_to_i(valc, fast), None, ntv[1].to_obj(), None, leng)
129        return (nam, typ, cls.n_to_i(val, fast), None, None, None, len(ntv))

Generate a tuple data from a Ntv value(bytes, string, json, Ntv object)

Parameters

  • field : bytes, string json or Ntv object to convert
  • format : string (default 'json') - format to convert ntv_value
  • fast: boolean (default False) - if True, codec is created without conversion, else codec is created with json structure

Returns

  • tuple : name, dtype, codec, parent, keys, coef, leng name (None or string): name of the Field dtype (None or string): type of data codec (list): list of Field codec values parent (None or int): Field parent or None keys (None or list): Field keys coef (None or int): coef if primary Field else None leng (int): length of the Field
@staticmethod
def encode_coef(lis):
131    @staticmethod 
132    def encode_coef(lis):
133        '''Generate a repetition coefficient for periodic list'''
134        if len(lis) < 2:
135            return 0
136        coef = 1
137        while coef != len(lis):
138            if lis[coef-1] != lis[coef]:
139                break
140            coef += 1
141        #print('coef : ', coef)
142        '''coef = 0
143        for i in range(1,len(lis)):
144            coef = i
145            if lis[i-1] != lis[i]:
146                break'''
147        if (not len(lis) % (coef * (max(lis) + 1)) and 
148            lis == FieldInterface.keysfromcoef(coef, max(lis) + 1, len(lis))):
149            return coef
150        return 0

Generate a repetition coefficient for periodic list

@staticmethod
def keysfromcoef(coef, period, leng=None):
152    @staticmethod 
153    def keysfromcoef(coef, period, leng=None):
154        ''' return a list of keys with periodic structure'''
155        if not leng:
156            leng = coef * period
157        return None if not coef or not period else [ (ikey % (coef * period)) // coef 
158                                                    for ikey in range(leng)]

return a list of keys with periodic structure

def to_dict_obj( self, typevalue=None, simpleval=False, modecodec='optimize', **kwargs):
160    def to_dict_obj(self, typevalue=None, simpleval=False, modecodec='optimize', **kwargs):
161        '''deprecated method'''
162        option = {'encoded': False, 'format': 'json', 'untyped': False,
163                  'codif': {}, 'geojson': False} | kwargs
164        dic = {}
165        if self.typevalue:
166            dic['type'] = self.typevalue
167        ds = pd.Series(range(len(self.keys)), index=self.keys, dtype='int64')
168        dic['value'] = [{'record': ds[i].tolist(),
169                         'codec': util.json(cod, encoded=False, typevalue=None,
170                                            simpleval=simpleval, modecodec=modecodec,
171                                            untyped=option['untyped'], datetime=False,
172                                            geojson=option['geojson'])}
173                        for i, cod in enumerate(self.codec)]
174        return {self.name: dic}

deprecated method

def to_numpy(self, func=None, codec=False, npdtype=None, **kwargs):
176    def to_numpy(self, func=None, codec=False, npdtype=None, **kwargs):
177        '''
178        Transform Field in a Numpy array.
179
180        *Parameters*
181
182        - **func** : function (default None) - function to apply for each value of the Field.
183        If func is the 'index' string, values are replaced by raw values.
184        - **npdtype** : string (default None) - numpy dtype for the Array ('object' if None)
185        - **kwargs** : parameters to apply to the func function
186
187        *Returns* : Numpy Array'''
188        return self.to_pandas(func=func, codec=codec, npdtype=npdtype, numpy=True, **kwargs)

Transform Field in a Numpy array.

Parameters

  • func : function (default None) - function to apply for each value of the Field. If func is the 'index' string, values are replaced by raw values.
  • npdtype : string (default None) - numpy dtype for the Array ('object' if None)
  • kwargs : parameters to apply to the func function

Returns : Numpy Array

def to_ntv( self, modecodec='optimize', codecval=False, def_type=None, keys=None, parent=None, name=True, coef=None):
190    def to_ntv(self, modecodec='optimize', codecval=False, def_type=None, 
191               keys=None, parent=None, name=True, coef=None):
192        '''Return a Ntv field value
193
194        *Parameters (kwargs)*
195
196        - **modecodec** : string (default 'optimize') - if 'full', index is with a full codec
197        if 'default' index has keys, if 'optimize' keys are optimized, 
198        - **codecval** : boolean (default False) - if True, only list of codec values is included
199        - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet
200        - **name** : boolean (default False) - if False, default index name are not included
201        - **keys** : list (default None) - used only with 'optimize' mode
202        - **parent** : int or str (default None) - used only with 'optimize' mode
203
204        *Returns* : Ntv object'''
205        leng = len(self)
206        codec = self.i_to_n(self.codec)
207        def_type = codec[0].ntv_type if not def_type and codec else def_type
208        idxname = None if self.name == '$default' or not name else self.name       
209        '''if len(self.codec) == 1:
210            return NtvSingle(self.codec[0].ntv_value, idxname, self.codec[0].ntv_type)
211        if codecval:
212            return NtvList(self.codec, idxname, ntv_type=def_type)
213        if len(self.codec) == leng or modecodec == 'full':
214            return NtvList(self.values, idxname, ntv_type=def_type)
215        if modecodec == 'default':
216            return NtvList([NtvList(self.codec, ntv_type=def_type), 
217                            NtvList(self.keys, ntv_type='json')], idxname, ntv_type='json')
218        if modecodec == 'optimize':
219            ntv_value = [NtvList(self.codec, ntv_type=def_type)]'''
220        if leng == 1 or len(codec) == 1 and modecodec != 'full':
221            return NtvSingle(codec[0].ntv_value, idxname, codec[0].ntv_type)
222        if codecval or modecodec == 'nokeys':
223            return NtvList(codec, idxname, ntv_type=def_type)
224        if len(codec) == leng or modecodec == 'full':
225            #if (len(codec) == leng and not self.keys) or modecodec == 'full':
226            #return NtvList(self.l_to_e(self.values), idxname, ntv_type=def_type)
227            return NtvList(self.values, idxname, ntv_type=def_type)
228        if modecodec == 'default':
229            return NtvList([NtvList(codec, ntv_type=def_type), 
230                            NtvList(self.keys, ntv_type='json')], idxname, ntv_type='json')
231        if coef:
232            return NtvList([NtvList(codec, ntv_type=def_type),
233                         NtvList([coef], ntv_type='json')], idxname, ntv_type='json')                        
234        if modecodec == 'optimize':
235            ntv_value = [NtvList(codec, ntv_type=def_type)]
236            if not parent is None:
237                ntv_value.append(NtvSingle(parent, ntv_type='json'))
238            if keys:
239                ntv_value.append(NtvList(keys, ntv_type='json'))    
240            elif parent is None:
241                ntv_value.append(NtvList(self.keys, ntv_type='json'))
242            return NtvList(ntv_value, idxname, ntv_type='json')                

Return a Ntv field value

Parameters (kwargs)

  • modecodec : string (default 'optimize') - if 'full', index is with a full codec if 'default' index has keys, if 'optimize' keys are optimized,
  • codecval : boolean (default False) - if True, only list of codec values is included
  • def_type : string (default 'json') - default ntv_type for NtvList or NtvSet
  • name : boolean (default False) - if False, default index name are not included
  • keys : list (default None) - used only with 'optimize' mode
  • parent : int or str (default None) - used only with 'optimize' mode

Returns : Ntv object

def to_pandas( self, func=None, codec=False, npdtype=None, series=True, index=True, numpy=False, **kwargs):
244    def to_pandas(self, func=None, codec=False, npdtype=None,
245                  series=True, index=True, numpy=False, **kwargs):
246        '''
247        Transform Field in a Pandas Series, Pandas DataFrame or Numpy array.
248
249        *Parameters*
250
251        - **func** : function (default None) - function to apply for each value of the Field.
252        If func is the 'index' string, values are replaced by raw values.
253        - **npdtype** : string (default None) - numpy dtype for the Array ('object' if None)
254        - **series** : boolean (default True) - if True, return a Series. 
255        If False return a DataFrame
256        - **index** : boolean (default True) - if True, index is keys.
257        - **numpy** : boolean (default False) - if True, return a Numpy array.
258        - **kwargs** : parameters to apply to the func function
259
260        *Returns* : Pandas Series, Pandas DataFrame, Numpy Array'''
261        if len(self) == 0:
262            raise FieldError("Dataset is empty")
263        if npdtype:
264            npdtype = np.dtype(npdtype)
265        else:
266            npdtype = 'object'
267        if func is None:
268            func = identity
269        if func == 'index':
270            return np.array(list(range(len(self))))
271        if not codec:
272            values = util.funclist(self.values, func, **kwargs)
273        else:
274            values = util.funclist(self._codec, func, **kwargs)
275        npdtype1 = npdtype
276        if isinstance(values[0], (datetime.datetime)):
277            npdtype1 = np.datetime64
278        # else:
279        #    npdtype=None
280        pdindex = None
281        if index:
282            pdindex = self._keys
283        try:
284            if numpy:
285                return np.array(values, dtype=npdtype1)
286            if series:
287                return pd.Series(values, dtype=npdtype1,
288                                 index=pdindex, name=self.name)
289            return pd.DataFrame(pd.Series(values, dtype=npdtype1,
290                                          index=pdindex, name=self.name))
291        except:
292            if numpy:
293                return np.array(values, dtype=npdtype)
294            if series:
295                return pd.Series(values, dtype=npdtype,
296                                 index=pdindex, name=self.name)
297            return pd.DataFrame(pd.Series(values, dtype=npdtype,
298                                          index=pdindex, name=self.name))

Transform Field in a Pandas Series, Pandas DataFrame or Numpy array.

Parameters

  • func : function (default None) - function to apply for each value of the Field. If func is the 'index' string, values are replaced by raw values.
  • npdtype : string (default None) - numpy dtype for the Array ('object' if None)
  • series : boolean (default True) - if True, return a Series. If False return a DataFrame
  • index : boolean (default True) - if True, index is keys.
  • numpy : boolean (default False) - if True, return a Numpy array.
  • kwargs : parameters to apply to the func function

Returns : Pandas Series, Pandas DataFrame, Numpy Array

def vlist(self, func, *args, extern=True, **kwargs):
300    def vlist(self, func, *args, extern=True, **kwargs):
301        '''
302        Apply a function to values and return the result.
303
304        *Parameters*
305
306        - **func** : function - function to apply to values
307        - **args, kwargs** : parameters for the function
308        - **extern** : if True, the function is apply to external values, else internal
309
310        *Returns* : list of func result'''
311        if extern:
312            return util.funclist(self.val, func, *args, **kwargs)
313        return util.funclist(self.values, func, *args, **kwargs)

Apply a function to values and return the result.

Parameters

  • func : function - function to apply to values
  • args, kwargs : parameters for the function
  • extern : if True, the function is apply to external values, else internal

Returns : list of func result

def vName(self, default='', maxlen=None):
315    def vName(self, default=ES.nullName, maxlen=None):
316        '''
317        Return the list of name for ESValue data .
318
319        *Parameters*
320
321        - **default** : value return if no name is available
322        - **maxlen** : integer (default None) - max length of name
323
324        *Returns* : list of name founded'''
325        #return [util.cast(val, dtype='name', default=default, maxlen=maxlen) for val in self.values]
326        return [self.i_to_name(val) for val in self.values]

Return the list of name for ESValue data .

Parameters

  • default : value return if no name is available
  • maxlen : integer (default None) - max length of name

Returns : list of name founded