# 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
            nb_select = int(max(len(group) * self.prop_select, min(self.min_select_per_industry, len(group))))
            largest_score = top(group, n=nb_select, column=self.score.name)
            weight_append = pd.DataFrame({INDEX_SELECTOR.col_name: [weight / nb_select] * nb_select,
                                          self.industry_code.name: [name] * nb_select},
                                         index=largest_score.index)

            ret = pd.concat([ret, pd.concat([largest_score[self.score.name], weight_append], axis=1)],
                            axis=0)

        return ret.reset_index() if self.reset_index else ret


class BrutalSelector(BaseEstimator, TransformerMixin):
    def __init__(self, nb_select=10, prop_select=0.1, reset_index=False):
        self.nb_select = nb_select
        self.prop_select = prop_select
        self.reset_index = reset_index

    def fit(self, X):
        return self

    @preprocess(X=ensure_pd_series)
    def transform(self, X):
        """
        :param X: pd.Series
        :return: 
        """

        ret = pd.DataFrame()
        nb_select = self.nb_select if self.nb_select is not None else int(len(X) * self.prop_select)

# 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

            nb_select = int(max(len(group) * self.prop_select, min(self.min_select_per_industry, len(group))))
            largest_score = top(group, n=nb_select, column=self.score.name)
            weight_append = pd.DataFrame({INDEX_SELECTOR.col_name: [weight / nb_select] * nb_select,
                                          self.industry_code.name: [name] * nb_select},
                                         index=largest_score.index)

            ret = pd.concat([ret, pd.concat([largest_score[self.score.name], weight_append], axis=1)],
                            axis=0)

        return ret.reset_index() if self.reset_index else ret


class BrutalSelector(BaseEstimator, TransformerMixin):
    def __init__(self, nb_select=10, prop_select=0.1, reset_index=False):
        self.nb_select = nb_select
        self.prop_select = prop_select
        self.reset_index = reset_index

    def fit(self, X):
        return self

    @preprocess(X=ensure_pd_series)
    def transform(self, X):
        """
        :param X: pd.Series
        :return: 
        """

        ret = pd.DataFrame()
        nb_select = self.nb_select if self.nb_select is not None else int(len(X) * self.prop_select)

        largest_score = top(X, n=nb_select)