def encode(obj):
    """
    Data encoder
    """
    tobj = type(obj)
    if isinstance(obj, Index):
        if isinstance(obj, RangeIndex):
            return {'typ': 'range_index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'start': getattr(obj, '_start', None),
                    'stop': getattr(obj, '_stop', None),
                    'step': getattr(obj, '_step', None)}
        elif isinstance(obj, PeriodIndex):
            return {'typ': 'period_index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'freq': getattr(obj, 'freqstr', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.asi8),
                    'compress': compressor}
        elif isinstance(obj, DatetimeIndex):
            tz = getattr(obj, 'tz', None)

            # store tz info and data as UTC
            if tz is not None:
                tz = tz.zone
                obj = obj.tz_convert('UTC')
            return {'typ': 'datetime_index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.asi8),
                    'freq': getattr(obj, 'freqstr', None),
                    'tz': tz,
                    'compress': compressor}
        elif isinstance(obj, (IntervalIndex, IntervalArray)):
            if isinstance(obj, IntervalIndex):
                typ = 'interval_index'
            else:
                typ = 'interval_array'
            return {'typ': typ,
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'left': getattr(obj, 'left', None),
                    'right': getattr(obj, 'right', None),
                    'closed': getattr(obj, 'closed', None)}
        elif isinstance(obj, MultiIndex):
            return {'typ': 'multi_index',
                    'klass': obj.__class__.__name__,
                    'names': getattr(obj, 'names', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.values),
                    'compress': compressor}
        else:
            return {'typ': 'index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.values),
                    'compress': compressor}

    elif isinstance(obj, Categorical):
        return {'typ': 'category',
                'klass': obj.__class__.__name__,
                'name': getattr(obj, 'name', None),
                'codes': obj.codes,
                'categories': obj.categories,
                'ordered': obj.ordered,
                'compress': compressor}

    elif isinstance(obj, Series):
        if isinstance(obj, SparseSeries):
            raise NotImplementedError(
                'msgpack sparse series is not implemented'
            )
            # d = {'typ': 'sparse_series',
            #     'klass': obj.__class__.__name__,
            #     'dtype': obj.dtype.name,
            #     'index': obj.index,
            #     'sp_index': obj.sp_index,
            #     'sp_values': convert(obj.sp_values),
            #     'compress': compressor}
            # for f in ['name', 'fill_value', 'kind']:
            #    d[f] = getattr(obj, f, None)
            # return d
        else:
            return {'typ': 'series',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'index': obj.index,
                    'dtype': obj.dtype.name,
                    'data': convert(obj.values),
                    'compress': compressor}
    elif issubclass(tobj, NDFrame):
        if isinstance(obj, SparseDataFrame):
            raise NotImplementedError(
                'msgpack sparse frame is not implemented'
            )
            # d = {'typ': 'sparse_dataframe',
            #     'klass': obj.__class__.__name__,
            #     'columns': obj.columns}
            # for f in ['default_fill_value', 'default_kind']:
            #    d[f] = getattr(obj, f, None)
            # d['data'] = dict([(name, ss)
            #                 for name, ss in obj.items()])
            # return d
        else:

            data = obj._data
            if not data.is_consolidated():
                data = data.consolidate()

            # the block manager
            return {'typ': 'block_manager',
                    'klass': obj.__class__.__name__,
                    'axes': data.axes,
                    'blocks': [{'locs': b.mgr_locs.as_array,
                                'values': convert(b.values),
                                'shape': b.values.shape,
                                'dtype': b.dtype.name,
                                'klass': b.__class__.__name__,
                                'compress': compressor} for b in data.blocks]
                    }

    elif isinstance(obj, (datetime, date, np.datetime64, timedelta,
                          np.timedelta64)) or obj is NaT:
        if isinstance(obj, Timestamp):
            tz = obj.tzinfo
            if tz is not None:
                tz = tz.zone
            freq = obj.freq
            if freq is not None:
                freq = freq.freqstr
            return {'typ': 'timestamp',
                    'value': obj.value,
                    'freq': freq,
                    'tz': tz}
        if obj is NaT:
            return {'typ': 'nat'}
        elif isinstance(obj, np.timedelta64):
            return {'typ': 'timedelta64',
                    'data': obj.view('i8')}
        elif isinstance(obj, timedelta):
            return {'typ': 'timedelta',
                    'data': (obj.days, obj.seconds, obj.microseconds)}
        elif isinstance(obj, np.datetime64):
            return {'typ': 'datetime64',
                    'data': str(obj)}
        elif isinstance(obj, datetime):
            return {'typ': 'datetime',
                    'data': obj.isoformat()}
        elif isinstance(obj, date):
            return {'typ': 'date',
                    'data': obj.isoformat()}
        raise Exception(
            "cannot encode this datetimelike object: {obj}".format(obj=obj))
    elif isinstance(obj, Period):
        return {'typ': 'period',
                'ordinal': obj.ordinal,
                'freq': obj.freqstr}
    elif isinstance(obj, Interval):
        return {'typ': 'interval',
                'left': obj.left,
                'right': obj.right,
                'closed': obj.closed}
    elif isinstance(obj, BlockIndex):
        return {'typ': 'block_index',
                'klass': obj.__class__.__name__,
                'blocs': obj.blocs,
                'blengths': obj.blengths,
                'length': obj.length}
    elif isinstance(obj, IntIndex):
        return {'typ': 'int_index',
                'klass': obj.__class__.__name__,
                'indices': obj.indices,
                'length': obj.length}
    elif isinstance(obj, np.ndarray):
        return {'typ': 'ndarray',
                'shape': obj.shape,
                'ndim': obj.ndim,
                'dtype': obj.dtype.name,
                'data': convert(obj),
                'compress': compressor}
    elif isinstance(obj, np.number):
        if np.iscomplexobj(obj):
            return {'typ': 'np_scalar',
                    'sub_typ': 'np_complex',
                    'dtype': obj.dtype.name,
                    'real': obj.real.__repr__(),
                    'imag': obj.imag.__repr__()}
        else:
            return {'typ': 'np_scalar',
                    'dtype': obj.dtype.name,
                    'data': obj.__repr__()}
    elif isinstance(obj, complex):
        return {'typ': 'np_complex',
                'real': obj.real.__repr__(),
                'imag': obj.imag.__repr__()}

    return obj
def encode ( obj ) : tobj = type ( obj ) if isinstance ( obj , Index ) : if isinstance ( obj , RangeIndex ) : return { 'typ' : 'range_index' , 'klass' : obj . __class__ . __name__ , 'name' : getattr ( obj , 'name' , None ) , 'start' : getattr ( obj , '_start' , None ) , 'stop' : getattr ( obj , '_stop' , None ) , 'step' : getattr ( obj , '_step' , None ) } elif isinstance ( obj , PeriodIndex ) : return { 'typ' : 'period_index' , 'klass' : obj . __class__ . __name__ , 'name' : getattr ( obj , 'name' , None ) , 'freq' : getattr ( obj , 'freqstr' , None ) , 'dtype' : obj . dtype . name , 'data' : convert ( obj . asi8 ) , 'compress' : compressor } elif isinstance ( obj , DatetimeIndex ) : tz = getattr ( obj , 'tz' , None ) if tz is not None : tz = tz . zone obj = obj . tz_convert ( 'UTC' ) return { 'typ' : 'datetime_index' , 'klass' : obj . __class__ . __name__ , 'name' : getattr ( obj , 'name' , None ) , 'dtype' : obj . dtype . name , 'data' : convert ( obj . asi8 ) , 'freq' : getattr ( obj , 'freqstr' , None ) , 'tz' : tz , 'compress' : compressor } elif isinstance ( obj , ( IntervalIndex , IntervalArray ) ) : if isinstance ( obj , IntervalIndex ) : typ = 'interval_index' else : typ = 'interval_array' return { 'typ' : typ , 'klass' : obj . __class__ . __name__ , 'name' : getattr ( obj , 'name' , None ) , 'left' : getattr ( obj , 'left' , None ) , 'right' : getattr ( obj , 'right' , None ) , 'closed' : getattr ( obj , 'closed' , None ) } elif isinstance ( obj , MultiIndex ) : return { 'typ' : 'multi_index' , 'klass' : obj . __class__ . __name__ , 'names' : getattr ( obj , 'names' , None ) , 'dtype' : obj . dtype . name , 'data' : convert ( obj . values ) , 'compress' : compressor } else : return { 'typ' : 'index' , 'klass' : obj . __class__ . __name__ , 'name' : getattr ( obj , 'name' , None ) , 'dtype' : obj . dtype . name , 'data' : convert ( obj . values ) , 'compress' : compressor } elif isinstance ( obj , Categorical ) : return { 'typ' : 'category' , 'klass' : obj . __class__ . __name__ , 'name' : getattr ( obj , 'name' , None ) , 'codes' : obj . codes , 'categories' : obj . categories , 'ordered' : obj . ordered , 'compress' : compressor } elif isinstance ( obj , Series ) : if isinstance ( obj , SparseSeries ) : raise NotImplementedError ( 'msgpack sparse series is not implemented' ) else : return { 'typ' : 'series' , 'klass' : obj . __class__ . __name__ , 'name' : getattr ( obj , 'name' , None ) , 'index' : obj . index , 'dtype' : obj . dtype . name , 'data' : convert ( obj . values ) , 'compress' : compressor } elif issubclass ( tobj , NDFrame ) : if isinstance ( obj , SparseDataFrame ) : raise NotImplementedError ( 'msgpack sparse frame is not implemented' ) else : data = obj . _data if not data . is_consolidated ( ) : data = data . consolidate ( ) return { 'typ' : 'block_manager' , 'klass' : obj . __class__ . __name__ , 'axes' : data . axes , 'blocks' : [ { 'locs' : b . mgr_locs . as_array , 'values' : convert ( b . values ) , 'shape' : b . values . shape , 'dtype' : b . dtype . name , 'klass' : b . __class__ . __name__ , 'compress' : compressor } for b in data . blocks ] } elif isinstance ( obj , ( datetime , date , np . datetime64 , timedelta , np . timedelta64 ) ) or obj is NaT : if isinstance ( obj , Timestamp ) : tz = obj . tzinfo if tz is not None : tz = tz . zone freq = obj . freq if freq is not None : freq = freq . freqstr return { 'typ' : 'timestamp' , 'value' : obj . value , 'freq' : freq , 'tz' : tz } if obj is NaT : return { 'typ' : 'nat' } elif isinstance ( obj , np . timedelta64 ) : return { 'typ' : 'timedelta64' , 'data' : obj . view ( 'i8' ) } elif isinstance ( obj , timedelta ) : return { 'typ' : 'timedelta' , 'data' : ( obj . days , obj . seconds , obj . microseconds ) } elif isinstance ( obj , np . datetime64 ) : return { 'typ' : 'datetime64' , 'data' : str ( obj ) } elif isinstance ( obj , datetime ) : return { 'typ' : 'datetime' , 'data' : obj . isoformat ( ) } elif isinstance ( obj , date ) : return { 'typ' : 'date' , 'data' : obj . isoformat ( ) } raise Exception ( "cannot encode this datetimelike object: {obj}" . format ( obj = obj ) ) elif isinstance ( obj , Period ) : return { 'typ' : 'period' , 'ordinal' : obj . ordinal , 'freq' : obj . freqstr } elif isinstance ( obj , Interval ) : return { 'typ' : 'interval' , 'left' : obj . left , 'right' : obj . right , 'closed' : obj . closed } elif isinstance ( obj , BlockIndex ) : return { 'typ' : 'block_index' , 'klass' : obj . __class__ . __name__ , 'blocs' : obj . blocs , 'blengths' : obj . blengths , 'length' : obj . length } elif isinstance ( obj , IntIndex ) : return { 'typ' : 'int_index' , 'klass' : obj . __class__ . __name__ , 'indices' : obj . indices , 'length' : obj . length } elif isinstance ( obj , np . ndarray ) : return { 'typ' : 'ndarray' , 'shape' : obj . shape , 'ndim' : obj . ndim , 'dtype' : obj . dtype . name , 'data' : convert ( obj ) , 'compress' : compressor } elif isinstance ( obj , np . number ) : if np . iscomplexobj ( obj ) : return { 'typ' : 'np_scalar' , 'sub_typ' : 'np_complex' , 'dtype' : obj . dtype . name , 'real' : obj . real . __repr__ ( ) , 'imag' : obj . imag . __repr__ ( ) } else : return { 'typ' : 'np_scalar' , 'dtype' : obj . dtype . name , 'data' : obj . __repr__ ( ) } elif isinstance ( obj , complex ) : return { 'typ' : 'np_complex' , 'real' : obj . real . __repr__ ( ) , 'imag' : obj . imag . __repr__ ( ) } return obj
Data encoder