Esempio n. 1
0
def cube(axes, values=None, broadcast=True, dtype=None):
    """Create a cube  object. 
    axes: list of axis of the cube
    values: optional, list of values of the cube. Can be other cubes for build a report.
    Ex.
        cp.cube([time])
        cp.cube([time,product])
        cp.cube([time,product],[10,20,30,40,50,60,70,80])
        cp.cube([time,product],cp.random)
        
        cp.cube([index_reports],[report_1,report_2])
    """
    if values is None:
        if not dtype is None:
            if dtype is str:
                return cubepy.Cube.full(axes, '', dtype='U25')
            elif kindToString(np.dtype(dtype).kind) == "string":
                return cubepy.Cube.full(axes, '', dtype=dtype)
        return cubepy.Cube.zeros(axes)
    else:
        if isinstance(values, list) or isinstance(values, np.ndarray):
            if len(values) > 0:
                if isinstance(values[0], cubepy.Cube):
                    #use stack
                    if isinstance(axes, list):
                        axes = axes[0]
                    return cubepy.stack(values, axes, broadcast)
            return cubepy.Cube(axes, values, fillValues=True, dtype=dtype)
        elif isinstance(values, numbers.Number) and values == random:
            theSize = [len(x) for x in axes]
            return cube(axes,
                        np.random.randint(100, size=theSize),
                        dtype=dtype)
        else:
            return cubepy.Cube.full(axes, values, dtype=dtype)
Esempio n. 2
0
def aggregate(cube, mapCube, indexToRemove, targetIndex):
    """ Aggregates the values in Cube to generate the result indexed by  targetIndex.
        Map gives the value of targetIndex for each element of indexToRemove

        Example for aggregating time information into annual index the syntax is:
            cp.aggregate(cube, map, time, years )
    """
    grouping_index_mat = cubepy.Cube([targetIndex], targetIndex.values)
    mat_allocation = mapCube == grouping_index_mat
    return (cube * mat_allocation).sum(indexToRemove)
        def hierarchize(cube, levels, maps):

            mapArray = nodeDic[maps[0]].result
            coordValues = mapArray.values.copy()
            targetIndexId = nodeDic[levels[1]].result.name

            for pos, level in enumerate(levels):
                if pos > 0:

                    if not maps[pos] is None:
                        mapArrayLevel = nodeDic[maps[pos]].result

                        for ii in range(len(coordValues)):
                            if not coordValues[ii] is None:
                                try:
                                    newVal = mapArrayLevel.filter(
                                        mapArrayLevel.dims[0],
                                        coordValues[ii]).values.item(0)
                                    coordValues[ii] = newVal
                                except Exception as ex:
                                    coordValues[ii] = None
                                    #raise ValueError("Hierarchy not found. Level: " + targetIndexId + ", value: " + coordValues[ii])
                                    pass

            # convert to dataarray
            _coords = []
            for _axis in cube.axes:
                _coord = pd.Index(_axis.values, name=_axis.name)
                _coords.append(_coord)
            dataArray = xr.DataArray(cube.values, _coords)

            # perform aggregate
            dataArray.coords[levels[0]].values = coordValues
            _df = dataArray.to_series()
            _df = _df.groupby(list(dataArray.dims), sort=False).agg(sby)
            _da = _df.to_xarray()
            reindex_dic = dict()
            for dimension in _da.dims:
                if dimension == levels[0]:
                    reindex_dic[dimension] = nodeDic[levels[-1:]
                                                     [0]].result.values
                elif dimension in nodeDic and isinstance(
                        nodeDic[dimension].result, cubepy.Index):
                    reindex_dic[dimension] = nodeDic[dimension].result.values

            _db = _da.reindex(reindex_dic)

            # convert to cube
            _indexes = []
            for _dim in _db.dims:
                _index = cubepy.Index(_dim, _db.coords[_dim].values)
                _indexes.append(_index)
            _cube = cubepy.Cube(_indexes, _db.values)

            return _cube
Esempio n. 4
0
def find(param1, param2, compareType=1, caseSensitive=True):
    """
    param1: value or indexarray for compare
    param2: index compare to
    compareType: cp.exact=1, cp.start_with=2, cp.end_with=3, cp.contain=4  
    caseSensitive: able to differentiate between uppercase and lowercase (by default True)

    If param1 is a scalar (numeric or str) and param2 is an index:  return cube indexed by param2 with True on ocurrences of param2
        Ex. result = cp.apply("te", region, cp.end_with)
    If param1 is an index and param2 is an index too:  return cube indexed by param1 and param2 with True on ocurrences of param1 on param2
        Ex. result = cp.apply(subregion, region, cp.contain)

    """
    def _fn(item, value):
        if isinstance(item, str) == False:
            item = str(item)
        if isinstance(value, str) == False:
            value = str(value)
        if compareType == 1:
            if caseSensitive:
                return item == value
            else:
                return item.lower() == value.lower()
        elif compareType == 2:
            if caseSensitive:
                return item[:len(value)] == value
            else:
                return item[:len(value)].lower() == value.lower()
        elif compareType == 3:
            if caseSensitive:
                return item[-len(value):] == value
            else:
                return item[-len(value):].lower() == value.lower()
        elif compareType == 4:
            if caseSensitive:
                return value in item
            else:
                return value.lower() in item.lower()

    if (isinstance(param1, str) or str(param1).isnumeric()) and isinstance(
            param2, cubepy.Index):
        vfn = np.vectorize(_fn)
        return cubepy.Cube([param2], vfn(param2.values, param1))

    if isinstance(param1, cubepy.Index) and isinstance(param2, cubepy.Index):
        _res = cubepy.Cube.full([param1, param2], False)
        rr = 0
        for row in param1.values:
            cc = 0
            for col in param2.values:
                _res.values[rr, cc] = _fn(col, row)
                cc += 1
            rr += 1
        return _res
Esempio n. 5
0
def apply(fn, param1, param2=None, start=None):
    """
    Apply functions to index and cubes. Multiple results can be obtained
    fn: function to apply
    param1: index or cube
    param2: index or cube
    start: scalar or cube
        Ex. 
            cp.apply(lambda x: x[:2] ,indexRegion): return new cube indexed by "indexRegion" and apply fn on each item
            cp.apply(lambda x: x*5 ,cubeSales): return new cube result of apply fn on all values of the cubeSales
            cp.apply( cp.addPeriods, start_proj , end_proj): Return new cube result of apply fn on "start_proj" with "end_proj"
            cp.apply(lambda x: x+1, indexYear, start=10) : Return new cube indexed by "indexYear", result of apply fn starting with scalar value "10"
            cp.apply(lambda x: x+1, indexYear, start=prices) : Return new cube indexed by "indexYear", result of apply fn starting with cube "prices"
    """
    if callable(fn):
        vfn = np.vectorize(fn)
        if param2 is None:
            if isinstance(param1, cubepy.Index):
                if start is None:
                    return cubepy.Cube([param1], vfn(param1.values))
                elif isinstance(start, cubepy.Cube):
                    values = [start.values]
                    numEls = len(param1)
                    for nn in range(numEls - 1):
                        values.append(fn(values[nn]))
                    new_axes = start._axes.insert(param1, 0)
                    return cubepy.Cube(new_axes, values)
                else:
                    values = [start]
                    numEls = len(param1)
                    for nn in range(numEls - 1):
                        values.append(fn(values[nn]))
                    return cubepy.Cube(param1, values)
            if isinstance(param1, cubepy.Cube):
                return param1.apply(fn)
        elif isinstance(param1, cubepy.Cube) and isinstance(
                param2, cubepy.Cube):
            return apply_op(param1, param2, vfn)
    return None
 def createCube(self, nodeId, npArray):
     _dimsNames = [
         self.AXISNAME + str(x) + "." + nodeId for x in range(npArray.ndim)
     ]
     _dimsValues = [
         list(x)
         for x in (range(npArray.shape[y]) for y in range(npArray.ndim))
     ]
     _indexes = [
         cubepy.Index(_dimsNames[x], _dimsValues[x])
         for x in range(len(_dimsNames))
     ]
     _cube = cubepy.Cube(_indexes, npArray)
     return _cube
    def cubeEvaluate(self,
                     result,
                     nodeDic,
                     nodeId,
                     dims=None,
                     rows=None,
                     columns=None,
                     summaryBy="sum",
                     bottomTotal=False,
                     rightTotal=False,
                     fromRow=0,
                     toRow=0):
        sby = safesum
        if summaryBy == 'avg':
            sby = safemean
        elif summaryBy == 'max':
            sby = safemax
        elif summaryBy == 'min':
            sby = safemin

        if (fromRow is None) or int(fromRow) <= 0:
            fromRow = 1
        if (toRow is None) or int(toRow) < 1:
            toRow = 100
        fromRow = int(fromRow)
        toRow = int(toRow)

        result = self.applyHierarchy(result, nodeDic, nodeId, dims, rows,
                                     columns, sby)

        _filters = []
        _rows = []
        _columns = []
        if not rows is None:
            for row in rows:
                if self.hasDim(result, str(row["field"])):
                    _rows.append(str(row["field"]))
                    self.addToFilter(nodeDic, row, _filters)

        if not columns is None:
            for column in columns:
                if self.hasDim(result, str(column["field"])):
                    _columns.append(str(column["field"]))
                    self.addToFilter(nodeDic, column, _filters)

        if not dims is None:
            for dim in dims:
                if self.hasDim(result, str(dim["field"])):
                    self.addToFilter(nodeDic, dim, _filters)

        tmp = None
        if len(_rows) == 0 and len(_columns) == 0 and result.ndim > 0:
            #_rows.append( result.dims[0] )
            tmp = cubepy.Cube([], result.filter(_filters).reduce(sby))

        else:
            tmp = result.filter(_filters).reduce(
                sby, keep=(_rows + _columns)).transpose(_rows + _columns)

        finalValues = tmp.values
        finalIndexes = []
        if tmp.ndim > 0:
            finalIndexes = tmp.axes[0].values
        finalColumns = ["Total"]
        if tmp.ndim == 2:
            finalColumns = tmp.axes[1].values

        # Add totales
        _totalRow = None
        if bottomTotal and len(_rows) > 0:
            # add total row
            #finalIndexes = np.append(finalIndexes,"Total")
            if tmp.ndim == 1:
                _totalRow = finalValues.sum(axis=0).reshape(1)
                #finalValues = np.append( finalValues, finalValues.sum(axis=0).reshape(1), axis=0)
            else:
                _totalRow = finalValues.sum(axis=0).reshape(
                    1, len(finalValues[0]))
                _totalRow = _totalRow[0]
                if rightTotal:
                    _totalRow = np.append(_totalRow, finalValues.sum())

        if rightTotal and len(_columns) > 0:
            # add total column
            if tmp.ndim == 1:
                finalIndexes = np.append(finalIndexes, "Total")
                finalValues = np.append(finalValues,
                                        finalValues.sum(axis=0).reshape(1),
                                        axis=0)
            else:
                finalColumns = np.append(finalColumns, "Total")
                finalValues = np.append(finalValues,
                                        finalValues.sum(axis=1).reshape(
                                            len(finalValues), 1),
                                        axis=1)

            # con una sola dimension

        # chek inf
        if kindToString(finalValues.dtype.kind) == "numeric":
            if np.isinf(finalValues).any():
                finalValues[np.isinf(finalValues)] = None

        # chec if haver nan values
        # if np.isnan(finalValues).any():
        if pd.isnull(finalValues).any():
            try:
                finalValues = np.where(np.isnan(finalValues), None,
                                       finalValues)
            except:
                finalValues[pd.isnull(finalValues)] = None

        res = {}
        pageInfo = None
        onRow = None
        onColumn = None
        if len(_rows) == 0 and len(_columns) == 0:
            res = {
                "columns": [],
                "index": ["Total"],
                "data": [[finalValues.tolist()]]
            }
        elif len(_rows) == 0:
            onColumn = _columns[0]
            res = {
                "columns": finalIndexes[:300].tolist(),
                "index": finalColumns,
                "data": [finalValues[:300].tolist()]
            }
        elif len(_columns) == 0:

            if (len(finalIndexes) > self.PAGESIZE):
                pageInfo = {
                    "fromRow": int(fromRow),
                    "toRow": int(toRow),
                    "totalRows": len(finalIndexes)
                }

            onRow = _rows[0]
            res = {
                "columns": finalColumns,
                "index": finalIndexes[fromRow - 1:toRow].tolist(),
                "data": [[x] for x in finalValues[fromRow - 1:toRow].tolist()]
            }
            # add total rows
            if not _totalRow is None:
                res["index"].append("Total")
                res["data"].append(_totalRow.tolist())

        else:
            onColumn = _columns[0]
            onRow = _rows[0]

            if (len(finalIndexes) > self.PAGESIZE):
                pageInfo = {
                    "fromRow": int(fromRow),
                    "toRow": int(toRow),
                    "totalRows": len(finalIndexes)
                }

            res = {
                "columns": finalColumns[:300].tolist(),
                "index": finalIndexes[fromRow - 1:toRow].tolist(),
                "data": finalValues[fromRow - 1:toRow, :300].tolist()
            }

            # add total rows
            if not _totalRow is None:
                res["index"].append("Total")
                res["data"].append(_totalRow[:300].tolist())

        return self.createResult(res,
                                 type(tmp),
                                 onRow=onRow,
                                 onColumn=onColumn,
                                 node=nodeDic[nodeId],
                                 pageInfo=pageInfo)