Repository: feature-engine/feature_engine (python)

Issue:
yeo-johnson inverse transform throws an erro
```
InvalidIndexError                         Traceback (most recent call last)
File ~\Documents\Repositories\envs\fe_not\lib\site-packages\pandas\core\series.py:1289, in Series.__setitem__(self, key, value)
   1288 try:
-> 1289     self._set_with_engine(key, value, warn=warn)
   1290 except KeyError:
   1291     # We have a scalar (or for MultiIndex or object-dtype, scalar-like)
   1292     #  key that is not present in self.index.

File ~\Documents\Repositories\envs\fe_not\lib\site-packages\pandas\core\series.py:1361, in Series._set_with_engine(self, key, value, warn)
   1360 def _set_with_engine(self, key, value, warn: bool = True) -> None:
-> 1361     loc = self.index.get_loc(key)
   1363     # this is equivalent to self._values[key] = value

File ~\Documents\Repositories\envs\fe_not\lib\site-packages\pandas\core\indexes\range.py:418, in RangeIndex.get_loc(self, key)
    417     raise KeyError(key)
--> 418 self._check_indexing_error(key)
    419 raise KeyError(key)

File ~\Documents\Repositories\envs\fe_not\lib\site-packages\pandas\core\indexes\base.py:6059, in Index._check_indexing_error(self, key)
   6056 if not is_scalar(key):
   6057     # if key is not a scalar, directly raise an error (the code below
   6058     # would convert to numpy arrays and raise later any way) - GH29926
-> 6059     raise InvalidIndexError(key)

InvalidIndexError: 64      True
682     True
960     True
1384    True
1100    True
        ... 
763     True
835     True
1216    True
559     True
684     True
Name: LotArea, Length: 1022, dtype: bool

During handling of the above exception, another exception occurred:

IndexingError                             Traceback (most recent call last)
Cell In [21], line 1
----> 1 train_unt = tf.inverse_transform(train_t)
      2 test_unt = tf.inverse_transform(test_t)

File c:\users\sole\documents\repositories\feature_engine\feature_engine\transformation\yeojohnson.py:181, in YeoJohnsonTransformer.inverse_transform(self, X)
    178 X = self._check_transform_input_and_state(X)
    180 for feature in self.variables_:
--> 181     X[feature] = self._inverse_transform_series(
    182         X[feature], lmbda=self.lambda_dict_[feature]
    183     )
    185 return X

File c:\users\sole\documents\repositories\feature_engine\feature_engine\transformation\yeojohnson.py:195, in YeoJohnsonTransformer._inverse_transform_series(self, X, lmbda)
    193     x_inv[pos] = np.exp(X[pos]) - 1
    194 else:  # lmbda != 0
--> 195     x_inv[pos] = np.power(X[pos] * lmbda + 1, 1 / lmbda) - 1
    197 # when x < 0
    198 if lmbda != 2:

File ~\Documents\Repositories\envs\fe_not\lib\site-packages\pandas\core\series.py:1329, in Series.__setitem__(self, key, value)
   1324     raise KeyError(
   1325         "key of type tuple not found and not a MultiIndex"
   1326     ) from err
   1328 if com.is_bool_indexer(key):
-> 1329     key = check_bool_indexer(self.index, key)
   1330     key = np.asarray(key, dtype=bool)
   1332     if (
   1333         is_list_like(value)
   1334         and len(value) != len(self)
   (...)
   1339         #  _where call below
   1340         # GH#44265

File ~\Documents\Repositories\envs\fe_not\lib\site-packages\pandas\core\indexing.py:2662, in check_bool_indexer(index, key)
   2660 indexer = result.index.get_indexer_for(index)
   2661 if -1 in indexer:
-> 2662     raise IndexingError(
   2663         "Unalignable boolean Series provided as "
   2664         "indexer (index of the boolean Series and of "
   2665         "the indexed object do not match)."
   2666     )
   2668 result = result.take(indexer)
   2670 # fall through for boolean

IndexingError: Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match).

```

Error can be reproduced by applying inverse_transform to the code we currently have in the user guide as demo

Pull request:
fix yeo-johnson inverse transform bug
closes #786 

Patch:
diff --git a/feature_engine/transformation/yeojohnson.py b/feature_engine/transformation/yeojohnson.py
index 5e33c05..f87d099 100644
--- a/feature_engine/transformation/yeojohnson.py
+++ b/feature_engine/transformation/yeojohnson.py
@@ -185,7 +185,7 @@ class YeoJohnsonTransformer(BaseNumericalTransformer):
         return X
 
     def _inverse_transform_series(self, X: pd.Series, lmbda: float) -> pd.Series:
-        x_inv = pd.Series(np.zeros_like(X))
+        x_inv = pd.Series(np.zeros_like(X), index=X.index)
         pos = X >= 0
 
         # when x >= 0


Test patch:
diff --git a/tests/test_transformation/test_yeojohnson_transformer.py b/tests/test_transformation/test_yeojohnson_transformer.py
index aeca364..f4eb32f 100644
--- a/tests/test_transformation/test_yeojohnson_transformer.py
+++ b/tests/test_transformation/test_yeojohnson_transformer.py
@@ -116,6 +116,25 @@ def test_inverse_with_X_negative_and_positive():
     pd.testing.assert_frame_equal(X, X_inverse, check_dtype=False)
 
 
+def test_inverse_with_with_non_linear_index():
+    X = pd.DataFrame(
+        {
+            "var1": np.arange(-20, 0),
+            "var2": np.arange(0, 20),
+            "var3": np.arange(-10, 10),
+        },
+        index=[13, 15, 12, 11, 17, 9, 4, 0, 1, 14, 18, 2, 3, 6, 5, 7, 8, 2, 16, 10]
+    )
+
+    transformer = YeoJohnsonTransformer(variables=None)
+    X_trans = transformer.fit_transform(X)
+
+    X_inverse = transformer.inverse_transform(X_trans)
+    X_inverse = X_inverse.round(0).astype(int)
+
+    pd.testing.assert_frame_equal(X, X_inverse, check_dtype=False)
+
+
 def test_lambda_equals_lambda_equal_0():
     X = pd.DataFrame(
         {