def _apply_filters(self, **filters):
        regexp = filters.pop('regexp', False)
        keep = np.array([True] * len(self.data))
        for col, values in filters.items():
            if values is None:
                continue
            if col in self.meta.columns:
                matches = pattern_match(self.meta[col], values, regexp=regexp)
                cat_idx = self.meta[matches].index
                keep_col = (self.data[META_IDX].set_index(META_IDX)
                                .index.isin(cat_idx))
            elif col == 'variable':
                level = filters['level'] if 'level' in filters else None
                keep_col = pattern_match(self.data[col], values, level, regexp)
            elif col == 'year':
                _data = self.data[col] if self.time_col is not 'time' \
                    else self.data['time'].apply(lambda x: x.year)
                keep_col = years_match(_data, values)
            elif col == 'month' and self.time_col is 'time':
                keep_col = month_match(self.data['time']
                                           .apply(lambda x: x.month),
                                       values)
            elif col == 'day' and self.time_col is 'time':
                if isinstance(values, str):
                    wday = True
                elif isinstance(values, list) and isinstance(values[0], str):
                    wday = True
                else:
                    wday = False
                if wday:
                    days = self.data['time'].apply(lambda x: x.weekday())
                else:
                    days = self.data['time'].apply(lambda x: x.day)
                keep_col = day_match(days, values)
            elif col == 'hour' and self.time_col is 'time':
                keep_col = hour_match(self.data['time']
                                          .apply(lambda x: x.hour),
                                      values)
            elif col == 'time' and self.time_col is 'time':
                keep_col = datetime_match(self.data[col], values)
            elif col == 'level':
                if 'variable' not in filters.keys():
                    keep_col = find_depth(self.data['variable'], level=values)
                else:
                    continue
            elif col in self.data.columns:
                keep_col = pattern_match(self.data[col], values, regexp=regexp)
            else:
                _raise_filter_error(col)
            keep &= keep_col
        return keep