Skip to content

Commit

Permalink
Merge 512c253 into 77c9df1
Browse files Browse the repository at this point in the history
  • Loading branch information
twheys committed Aug 16, 2016
2 parents 77c9df1 + 512c253 commit 2ecb054
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 19 deletions.
30 changes: 28 additions & 2 deletions docs/2_slicer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ For each |FeatureReference|, there are the following variations:

.. code-block:: python
from fireant.slicer import WoW, DeltaMoM, DeltaQoQ
from fireant.slicer.references import WoW, DeltaMoM, DeltaQoQ
slicer.notebook.column_index_table(
metrics=['clicks', 'conversions'],
Expand All @@ -328,4 +328,30 @@ For each |FeatureReference|, there are the following variations:
.. note::

For any reference, the comparison is made for the same days of the week.
For any reference, the comparison is made for the same days of the week.


Post-Processing Operations
--------------------------

Operations include extra computations that modify the final results.

Totals
""""""

Totals adds ``ROLLUP`` to the SQL query to load the data and aggregated across dimensions. It requires one or more dimension keys as parameters for the dimensions that should be totaled. The below example will add an extra line with the total clicks and conversions for each date in addition to the three lines for each device type, desktop, mobile and tablet.

.. code-block:: python
from fireant.slicer.operations import Totals
slicer.notebook.line_chart(
metrics=['clicks', 'conversions'],
dimensions=['date', 'device'],
operations=[Totals('device')],
)
L1 and L2 Loss
""""""""""""""

Coming soon
2 changes: 0 additions & 2 deletions fireant/slicer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# coding: utf-8
from .filters import EqualityFilter, ContainsFilter, RangeFilter, WildcardFilter
from .managers import SlicerException
from .operations import Rollup
from .references import WoW, MoM, QoQ, YoY, Delta, DeltaPercentage
from .schemas import (Slicer, Metric, Dimension, CategoricalDimension, ContinuousDimension, NumericInterval,
UniqueDimension, DatetimeDimension, DatetimeInterval, DimensionValue, EqualityOperator, Join)
6 changes: 3 additions & 3 deletions fireant/slicer/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ def schemas(self, slicer):
raise NotImplementedError


class Rollup(Operation):
def __init__(self, dimension_keys):
super(Rollup, self).__init__('rollup')
class Totals(Operation):
def __init__(self, *dimension_keys):
super(Totals, self).__init__('rollup')
self.dimension_keys = dimension_keys

def schemas(self, slicer):
Expand Down
25 changes: 14 additions & 11 deletions fireant/slicer/transformers/highcharts.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,18 @@ def _reorder_index_levels(self, data_frame, display_schema):
return reordered

def _make_series(self, data_frame, dim_ordinal, display_schema, reference=None):
# This value represents how many iterations over data_frame items per yAxis we have. It's the product of
# non-metric levels of the data_frame's columns. We want metrics to share the same yAxis for all dimensions.
yaxis_span = (np.product([len(l) for l in data_frame.columns.levels[1:]])
if isinstance(data_frame.columns, pd.MultiIndex)
else 1)
metrics = list(data_frame.columns.levels[0]
if isinstance(data_frame.columns, pd.MultiIndex)
else data_frame.columns)

return [self._make_series_item(idx, item, dim_ordinal, display_schema, int(i // yaxis_span), reference)
for i, (idx, item) in enumerate(data_frame.iteritems())]
return [self._make_series_item(idx, item, dim_ordinal, display_schema, metrics, reference)
for idx, item in data_frame.iteritems()]

def _make_series_item(self, idx, item, dim_ordinal, display_schema, y_axis, reference):
def _make_series_item(self, idx, item, dim_ordinal, display_schema, metrics, reference):
return {
'name': self._format_label(idx, dim_ordinal, display_schema, reference),
'data': self._format_data(item),
'yAxis': y_axis,
'yAxis': metrics.index(idx[0] if isinstance(idx, tuple) else idx),
'dashStyle': 'Dot' if reference else 'Solid'
}

Expand Down Expand Up @@ -187,13 +185,15 @@ def _unstack_levels(self, dimensions, dim_ordinal):


class HighchartsColumnTransformer(HighchartsLineTransformer):
def _make_series_item(self, idx, item, dim_ordinal, display_schema, y_axis, reference):
chart_type = 'column'

def _make_series_item(self, idx, item, dim_ordinal, display_schema, metrics, reference):
return {
'name': self._format_label(idx, dim_ordinal, display_schema, reference),
'data': [_format_data_point(x)
for x in item
if not np.isnan(x)],
'yAxis': y_axis
'yAxis': metrics.index(idx[0] if isinstance(idx, tuple) else idx),
}

def xaxis_options(self, data_frame, dim_ordinal, display_schema):
Expand Down Expand Up @@ -232,6 +232,9 @@ def _make_categories(data_frame, dim_ordinal, display_schema):
category_dimension = display_schema['dimensions'][0]
if 'label_options' in category_dimension:
return [category_dimension['label_options'].get(dim, dim)
# Pandas gives both NaN or None in the index depending on whether a level was unstacked
if dim and not (isinstance(dim, float) and np.isnan(dim))
else 'Totals'
for dim in data_frame.index]

if 'label_field' in category_dimension:
Expand Down
4 changes: 3 additions & 1 deletion fireant/tests/slicer/test_slicer_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from fireant import settings
from fireant.slicer import *
from fireant.slicer.operations import Totals
from fireant.slicer.references import *
from fireant.tests.database.mock_database import TestDatabase
from pypika import functions as fn, Tables, Case

Expand Down Expand Up @@ -702,7 +704,7 @@ def test_rollup_operation(self):
query_schema = self.test_slicer.manager.query_schema(
metrics=['foo'],
dimensions=['date', 'locale', 'account'],
operations=[Rollup(['locale', 'account'])],
operations=[Totals('locale', 'account')],
)

self.assertTrue({'table', 'metrics', 'dimensions', 'rollup'}.issubset(query_schema.keys()))
Expand Down

0 comments on commit 2ecb054

Please sign in to comment.