from functools import partial
from itertools import product
from string import ascii_letters
import warnings

import numpy as np

from pandas import (
    Categorical, DataFrame, MultiIndex, Series, TimeGrouper, Timestamp,
    date_range, period_range)
import pandas.util.testing as tm


method_blacklist = {
    'object': {'median', 'prod', 'sem', 'cumsum', 'sum', 'cummin', 'mean',
               'max', 'skew', 'cumprod', 'cummax', 'rank', 'pct_change', 'min',
               'var', 'mad', 'describe', 'std', 'quantile'},
    'datetime': {'median', 'prod', 'sem', 'cumsum', 'sum', 'mean', 'skew',
                 'cumprod', 'cummax', 'pct_change', 'var', 'mad', 'describe',
                 'std'}
}


class ApplyDictReturn(object):
    def setup(self):
        self.labels = np.arange(1000).repeat(10)
        self.data = Series(np.random.randn(len(self.labels)))

    def time_groupby_apply_dict_return(self):
        self.data.groupby(self.labels).apply(lambda x: {'first': x.values[0],
                                                        'last': x.values[-1]})


class Apply(object):

    def setup_cache(self):
        N = 10**4
        labels = np.random.randint(0, 2000, size=N)
        labels2 = np.random.randint(0, 3, size=N)
        df = DataFrame({'key': labels,
                        'key2': labels2,
                        'value1': np.random.randn(N),
                        'value2': ['foo', 'bar', 'baz', 'qux'] * (N // 4)
                        })
        return df

    def time_scalar_function_multi_col(self, df):
        df.groupby(['key', 'key2']).apply(lambda x: 1)

    def time_scalar_function_single_col(self, df):
        df.groupby('key').apply(lambda x: 1)

    @staticmethod
    def df_copy_function(g):
        # ensure that the group name is available (see GH #15062)
        g.name
        return g.copy()