jazzido / mondrian-rest

A REST interface for Mondrian ROLAP server
MIT License
32 stars 8 forks source link

Output ancestors in tabular (XLS, CSV) representations #3

Closed jazzido closed 7 years ago

jazzido commented 7 years ago

Python/Pandas implementation for reference:

    def to_pandas(self, filter_empty_measures=True):
        tidy = self.tidy
        columns = []
        table = []

        # header row
        if self._agg_params['parents']:
            slices = []
            for dd in tidy['axes']:
                slices.append(dd['level_depth'])
                for ancestor_level in self._cube.dimensions_by_name[dd['name']]['hierarchies'][0]['levels'][1:dd['level_depth']]:
                    columns += ['ID %s' % ancestor_level['caption'], ancestor_level['caption']]
                columns += ['ID %s' % dd['level'], dd['level']]

            # measure names
            columns += [m['caption'] for m in self._agg_params['measures']]

            for row in tidy['data']:
                r = []
                for j, cell in enumerate(row[:len(tidy['axes'])]):
                    for ancestor in cell['ancestors'][:slices[j]-1]:
                        r += [ancestor['key'], ancestor['caption']]
                    r += [cell['key'], cell['caption']]

                for mvalue in row[len(tidy['axes']):]:
                    r.append(mvalue)

                table.append(r)

        else: # no parents
            for dd in tidy['axes']:
                columns += ['ID %s' % dd['level'], dd['level']]
            # measure names
            columns += [m['caption'] for m in self._agg_params['measures']]

            for row in tidy['data']:
                r = []
                for cell in row[:len(tidy['axes'])]:
                    r += [cell['key'], cell['caption']]

                for mvalue in row[len(tidy['axes']):]:
                    r.append(mvalue)

                table.append(r)

        df = pd.DataFrame(table,
                          columns=columns) \
               .set_index(columns[:-len(self._agg_params['measures'])])

        if filter_empty_measures:
            df = df[reduce_(np.logical_and,
                            [df[msr['name']].notnull()
                            for msr in self.measures])]

        return df