# Path: bamboo/core/aggregations.py
# AGGREGATIONS = {
#     cls.formula_name: cls for cls in
#     Aggregation.__subclasses__()
#     if cls.formula_name
# }
# 
# Path: bamboo/core/frame.py
# def add_parent_column(df, parent_dataset_id):
#     """Add parent ID column to this DataFrame."""
#     return add_constant_column(df, parent_dataset_id, PARENT_DATASET_ID)
# 
# def rows_for_parent_id(df, parent_id):
#     """DataFrame with only rows for `parent_id`.
# 
#     :param parent_id: The ID to restrict rows to.
# 
#     :returns: A DataFrame including only rows with a parent ID equal to
#         that passed in.
#     """
#     return df[df[PARENT_DATASET_ID] == parent_id].drop(PARENT_DATASET_ID, 1)
# 
# Path: bamboo/lib/parsing.py
# def parse_columns(dataset, formula, name, dframe=None, no_index=False):
#     """Parse a formula and return columns resulting from its functions.
# 
#     Parse a formula into a list of functions then apply those functions to
#     the Data Frame and return the resulting columns.
# 
#     :param formula: The formula to parse.
#     :param name: Name of the formula.
#     :param dframe: A DataFrame to apply functions to.
#     :param no_index: Drop the index on result columns.
#     """
#     functions = Parser.parse_functions(formula)
#     dependent_columns = Parser.dependent_columns(formula, dataset)
# 
#     # make select from dependent_columns
#     if dframe is None:
#         select = {col: 1 for col in dependent_columns or [MONGO_ID]}
# 
#         dframe = dataset.dframe(
#             query_args=QueryArgs(select=select),
#             keep_mongo_keys=True).set_index(MONGO_ID_ENCODED)
# 
#         if not dependent_columns:
#             # constant column, use dummy
#             dframe['dummy'] = 0
# 
#     return __build_columns(dataset, dframe, functions, name, no_index)


from pandas import concat
from bamboo.core.aggregations import AGGREGATIONS
from bamboo.core.frame import add_parent_column, rows_for_parent_id
from bamboo.lib.parsing import parse_columns
        aggregation = AGGREGATIONS.get(_type)
        self.aggregation = aggregation(self.name, self.groups, self.dframe)

    def save(self, dataset):
        """Save this aggregation.

        If an aggregated dataset for this aggregations group already exists
        store in this dataset, if not create a new aggregated dataset and store
        the aggregation in this new aggregated dataset.

        """
        new_dframe = self.aggregation.eval(self.columns)
        new_dframe = add_parent_column(new_dframe, dataset.dataset_id)

        a_dataset = dataset.aggregated_dataset(self.groups)

        if a_dataset is None:
            a_dataset = aggregated_dataset(dataset, new_dframe, self.groups)
        else:
            a_dframe = a_dataset.dframe()
            new_dframe = group_join(self.groups, a_dframe, new_dframe)
            a_dataset.replace_observations(new_dframe)

        self.new_dframe = new_dframe

    def update(self, dataset, child_dataset, formula, reducible):
        """Attempt to reduce an update and store."""
        parent_dataset_id = dataset.dataset_id

        # get dframe only including rows from this parent

# Path: bamboo/core/aggregations.py
# AGGREGATIONS = {
#     cls.formula_name: cls for cls in
#     Aggregation.__subclasses__()
#     if cls.formula_name
# }
# 
# Path: bamboo/core/frame.py
# def add_parent_column(df, parent_dataset_id):
#     """Add parent ID column to this DataFrame."""
#     return add_constant_column(df, parent_dataset_id, PARENT_DATASET_ID)
# 
# def rows_for_parent_id(df, parent_id):
#     """DataFrame with only rows for `parent_id`.
# 
#     :param parent_id: The ID to restrict rows to.
# 
#     :returns: A DataFrame including only rows with a parent ID equal to
#         that passed in.
#     """
#     return df[df[PARENT_DATASET_ID] == parent_id].drop(PARENT_DATASET_ID, 1)
# 
# Path: bamboo/lib/parsing.py
# def parse_columns(dataset, formula, name, dframe=None, no_index=False):
#     """Parse a formula and return columns resulting from its functions.
# 
#     Parse a formula into a list of functions then apply those functions to
#     the Data Frame and return the resulting columns.
# 
#     :param formula: The formula to parse.
#     :param name: Name of the formula.
#     :param dframe: A DataFrame to apply functions to.
#     :param no_index: Drop the index on result columns.
#     """
#     functions = Parser.parse_functions(formula)
#     dependent_columns = Parser.dependent_columns(formula, dataset)
# 
#     # make select from dependent_columns
#     if dframe is None:
#         select = {col: 1 for col in dependent_columns or [MONGO_ID]}
# 
#         dframe = dataset.dframe(
#             query_args=QueryArgs(select=select),
#             keep_mongo_keys=True).set_index(MONGO_ID_ENCODED)
# 
#         if not dependent_columns:
#             # constant column, use dummy
#             dframe['dummy'] = 0
# 
#     return __build_columns(dataset, dframe, functions, name, no_index)


# Path: bamboo/core/aggregator.py
from pandas import concat
from bamboo.core.aggregations import AGGREGATIONS
from bamboo.core.frame import add_parent_column, rows_for_parent_id
from bamboo.lib.parsing import parse_columns

        aggregation = AGGREGATIONS.get(_type)
        self.aggregation = aggregation(self.name, self.groups, self.dframe)

    def save(self, dataset):
        """Save this aggregation.

        If an aggregated dataset for this aggregations group already exists
        store in this dataset, if not create a new aggregated dataset and store
        the aggregation in this new aggregated dataset.

        """
        new_dframe = self.aggregation.eval(self.columns)
        new_dframe = add_parent_column(new_dframe, dataset.dataset_id)

        a_dataset = dataset.aggregated_dataset(self.groups)

        if a_dataset is None:
            a_dataset = aggregated_dataset(dataset, new_dframe, self.groups)
        else:
            a_dframe = a_dataset.dframe()
            new_dframe = group_join(self.groups, a_dframe, new_dframe)
            a_dataset.replace_observations(new_dframe)

        self.new_dframe = new_dframe

    def update(self, dataset, child_dataset, formula, reducible):
        """Attempt to reduce an update and store."""
        parent_dataset_id = dataset.dataset_id

        # get dframe only including rows from this parent

        dframe = rows_for_parent_id(child_dataset.dframe(