# Path: alphaware/base/factor_container.py
# def ensure_factor_container(func, argname, arg):
#     if isinstance(arg, FactorContainer):
#         return arg
#     else:
#         fc = FactorContainer(tiaocang_date=arg.trade_date_list)
#         fc.add_factor(arg)
#         return fc
# 
# Path: alphaware/base/factor_estimator.py
# class FactorEstimator(BaseEstimator):
#     def fit(self, factor_container, **kwargs):
#         return self
# 
#     @abstractmethod
#     def predict(self, factor_container):
#         return
# 
# Path: alphaware/enums.py
# class FactorType(StrEnum):
#     INDUSTY_CODE = 'industry_code'
#     ALPHA_FACTOR = 'alpha_factor'
#     RETURN = 'return'
#     PRICE = 'price'
#     ALPHA_FACTOR_MV = 'alpha_factor_mv'
#     SCORE = 'score'
#     FWD_RETURN = 'fwd_return'
#     WEIGHT = 'weight'
# 
# class SelectionMethod(StrEnum):
#     BRUTAL = 'brutal'
#     INDUSTRY_NEUTRAL = 'industry_neutral'
# 
# Path: alphaware/const.py
# INDEX_SELECTOR = namedtuple('INDEX_SELECTOR', ['date_index', 'sec_index', 'col_name'])
# 
# INDEX_FACTOR = namedtuple('INDEX_FACTOR', ['date_index', 'sec_index', 'full_index', 'col_score'])
# 
# INDEX_INDUSTRY_WEIGHT = namedtuple('INDEX_INDUSTRY_WEIGHT',
#                                    ['date_index', 'industry_index', 'full_index', 'col_name'])
# 
# Path: alphaware/utils/input_validation.py
# @expect_types(arg=(list, np.ndarray, pd.DataFrame, pd.Series))
# def ensure_pd_series(func, argname, arg):
#     if isinstance(arg, pd.Series):
#         return arg
#     elif isinstance(arg, pd.DataFrame):
#         return arg[arg.columns[0]]
#     else:
#         return pd.Series(arg)
# 
# Path: alphaware/utils/pandas_utils.py
# @expect_types(df=(pd.Series, pd.DataFrame))
# def top(df, column=None, n=5):
#     if isinstance(df, pd.Series):
#         ret = df.sort_values(ascending=False)[:n]
#     else:
#         py_assert(column is not None, "Specify the col name or use pandas Series type of data")
#         ret = df.sort_values(by=column, ascending=False)[:n]
# 
#     return ret


import pandas as pd
import numpy as np
import copy
from sklearn.base import (BaseEstimator,
                          TransformerMixin)
from sklearn_pandas import DataFrameMapper
from xutils import py_assert
from argcheck import preprocess
from itertools import chain
from alphaware.base import (ensure_factor_container,
                            FactorEstimator)
from alphaware.enums import (FactorType,
                             SelectionMethod)
from alphaware.const import (INDEX_SELECTOR,
                             INDEX_FACTOR,
                             INDEX_INDUSTRY_WEIGHT)
from alphaware.utils import ensure_pd_series, top
                                IndustryNeutralSelector(industry_weight=industry_weight,
                                                        prop_select=self.prop_select,
                                                        min_select_per_industry=self.min_select_per_industry,
                                                        reset_index=True))]
            else:
                data_mapper = [(score.name, BrutalSelector(nb_select=self.nb_select,
                                                           prop_select=self.prop_select,
                                                           reset_index=True))]
            data_mapper_by_date[date] = DataFrameMapper(data_mapper, input_df=True, df_out=True)

        return data_mapper_by_date

    def fit(self, factor_container, **kwargs):
        self.df_mapper = self._build_mapper(factor_container)
        return self

    @preprocess(factor_container=ensure_factor_container)
    def predict(self, factor_container):
        if self.copy:
            factor_container = copy.deepcopy(factor_container)
        tiaocang_date = factor_container.tiaocang_date
        selector_data = [self.df_mapper[date_].fit_transform(factor_container.data.loc[date_]) for date_ in
                         tiaocang_date]
        date_list = [[tiaocang_date[i]] * len(selector_data[i]) for i in range(len(selector_data))]
        date_agg = list(chain.from_iterable(date_list))
        selector_data_ = np.vstack(selector_data)
        selector_data_agg = np.column_stack((date_agg, selector_data_))

        data_df = pd.DataFrame(selector_data_agg)
        data_df.columns = [INDEX_FACTOR.date_index,

# Path: alphaware/base/factor_container.py
# def ensure_factor_container(func, argname, arg):
#     if isinstance(arg, FactorContainer):
#         return arg
#     else:
#         fc = FactorContainer(tiaocang_date=arg.trade_date_list)
#         fc.add_factor(arg)
#         return fc
# 
# Path: alphaware/base/factor_estimator.py
# class FactorEstimator(BaseEstimator):
#     def fit(self, factor_container, **kwargs):
#         return self
# 
#     @abstractmethod
#     def predict(self, factor_container):
#         return
# 
# Path: alphaware/enums.py
# class FactorType(StrEnum):
#     INDUSTY_CODE = 'industry_code'
#     ALPHA_FACTOR = 'alpha_factor'
#     RETURN = 'return'
#     PRICE = 'price'
#     ALPHA_FACTOR_MV = 'alpha_factor_mv'
#     SCORE = 'score'
#     FWD_RETURN = 'fwd_return'
#     WEIGHT = 'weight'
# 
# class SelectionMethod(StrEnum):
#     BRUTAL = 'brutal'
#     INDUSTRY_NEUTRAL = 'industry_neutral'
# 
# Path: alphaware/const.py
# INDEX_SELECTOR = namedtuple('INDEX_SELECTOR', ['date_index', 'sec_index', 'col_name'])
# 
# INDEX_FACTOR = namedtuple('INDEX_FACTOR', ['date_index', 'sec_index', 'full_index', 'col_score'])
# 
# INDEX_INDUSTRY_WEIGHT = namedtuple('INDEX_INDUSTRY_WEIGHT',
#                                    ['date_index', 'industry_index', 'full_index', 'col_name'])
# 
# Path: alphaware/utils/input_validation.py
# @expect_types(arg=(list, np.ndarray, pd.DataFrame, pd.Series))
# def ensure_pd_series(func, argname, arg):
#     if isinstance(arg, pd.Series):
#         return arg
#     elif isinstance(arg, pd.DataFrame):
#         return arg[arg.columns[0]]
#     else:
#         return pd.Series(arg)
# 
# Path: alphaware/utils/pandas_utils.py
# @expect_types(df=(pd.Series, pd.DataFrame))
# def top(df, column=None, n=5):
#     if isinstance(df, pd.Series):
#         ret = df.sort_values(ascending=False)[:n]
#     else:
#         py_assert(column is not None, "Specify the col name or use pandas Series type of data")
#         ret = df.sort_values(by=column, ascending=False)[:n]
# 
#     return ret


# Path: alphaware/selector.py
import pandas as pd
import numpy as np
import copy
from sklearn.base import (BaseEstimator,
                          TransformerMixin)
from sklearn_pandas import DataFrameMapper
from xutils import py_assert
from argcheck import preprocess
from itertools import chain
from alphaware.base import (ensure_factor_container,
                            FactorEstimator)
from alphaware.enums import (FactorType,
                             SelectionMethod)
from alphaware.const import (INDEX_SELECTOR,
                             INDEX_FACTOR,
                             INDEX_INDUSTRY_WEIGHT)
from alphaware.utils import ensure_pd_series, top

                                IndustryNeutralSelector(industry_weight=industry_weight,
                                                        prop_select=self.prop_select,
                                                        min_select_per_industry=self.min_select_per_industry,
                                                        reset_index=True))]
            else:
                data_mapper = [(score.name, BrutalSelector(nb_select=self.nb_select,
                                                           prop_select=self.prop_select,
                                                           reset_index=True))]
            data_mapper_by_date[date] = DataFrameMapper(data_mapper, input_df=True, df_out=True)

        return data_mapper_by_date

    def fit(self, factor_container, **kwargs):
        self.df_mapper = self._build_mapper(factor_container)
        return self

    @preprocess(factor_container=ensure_factor_container)
    def predict(self, factor_container):
        if self.copy:
            factor_container = copy.deepcopy(factor_container)
        tiaocang_date = factor_container.tiaocang_date
        selector_data = [self.df_mapper[date_].fit_transform(factor_container.data.loc[date_]) for date_ in
                         tiaocang_date]
        date_list = [[tiaocang_date[i]] * len(selector_data[i]) for i in range(len(selector_data))]
        date_agg = list(chain.from_iterable(date_list))
        selector_data_ = np.vstack(selector_data)
        selector_data_agg = np.column_stack((date_agg, selector_data_))

        data_df = pd.DataFrame(selector_data_agg)
        data_df.columns = [INDEX_FACTOR.date_index,

                           INDEX_FACTOR.sec_index,