Implement class to reverse item encodings

### Describe the workflow you want to enable

Hi! As a psychologist working with questionnaire data, you will find yourselves in situations where you have to reverse the values in certain variables (i.e. questionnaire items), because they have reversed logic (see [this link](https://psych.hanover.edu/classes/ResearchMethods/jamovi/reliability/reverseScoring.html) for an example).

### Describe your proposed solution

Implement a class that reverses variable values:

```python
class ReverseColumnValues(TransformerMixin,BaseEstimator):
    '''Reverse matrix column values. NaN values stay as they are'''
    
    def fit(self, X, y=None):
        return self
    
    def _reverse_array_values(self,a):
        '''Reverse values in a vector'''
        unique_vals = np.unique(a[~np.isnan(a)])  # Get unique non-nan values
        flip_dict = dict(zip(unique_vals,np.flip(unique_vals)))  # Create flip dictionary
        return np.vectorize(flip_dict.get)(a)  # map old values onto new values

    def _reverse_column_values(self,X):
        '''Reverse values of all columns of a matrix'''
        X_ = np.apply_along_axis(self._reverse_array_values,0,X)
        return X_
    
    def transform(self, X, y=None):
        return self._reverse_column_values(X)
```



### Describe alternatives you've considered, if relevant

Most certainly users would have to use this class as input to `ColumnTransformer` because you only want to reverse certain variables and leave the rest as it is.

### Additional context

Not sure though, if this might out of scope of scikit-learn. If not, maybe there's a contrib project that could use this?

COMMENT:
@ogrisel : I don't think that `OrdinalEncoder.inverse_transform` is related to this issue. Here's an example:

Consider the following example where subjects have to give ratings from 1 (do not agree) to 6 (fully agree) for each item in a depression questionnaire. Let's also assume we want to obtain a global depression score which is the sum of all items. This sum is only valid if high and low scores always have the same meaning. The last two items in this questionnaire are phrased in the 'opposite direction' so we have to reverse them (e.g. low happiness means more depressed):

```python

import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator,TransformerMixin

class ReverseColumnValues(TransformerMixin,BaseEstimator):
    '''Reverse matrix column values. NaN values stay as they are'''
    
    def fit(self, X, y=None):
        return self
    
    def _reverse_array_values(self,a):
        '''Reverse values in a vector'''
        unique_vals = np.unique(a[~np.isnan(a)])  # Get unique non-nan values
        flip_dict = dict(zip(unique_vals,np.flip(unique_vals)))  # Create flip dictionary
        return np.vectorize(flip_dict.get)(a)  # map old values onto new values

    def _reverse_column_values(self,X):
        '''Reverse values of all columns of a matrix'''
        X_ = np.apply_along_axis(self._reverse_array_values,0,X)
        return X_
    
    def transform(self, X, y=None):
        return self._reverse_column_values(X)


# create example dataframe
df = pd.DataFrame({'I_often_worry':[1.0,2.0,3.0,5.0,6.0],
                   'I_am_happy':[6.0,4.0,1.0,1.0,1.0],
                   'I_do_not_feel_sad':[5.0,3.0,2.0,1.0,1.0]})

# reverse the last two items
df[['I_am_happy','I_do_not_feel_sad']] = ReverseColumnValues().fit_transform(df[['I_am_happy','I_do_not_feel_sad']])

# create a global score which is the sum of all items and where high scores indicates higher depression score
df['depression'] = df.sum(axis=1)

```

Labels: New Feature, Needs Investigation