Repository: feature-engine/feature_engine

Issue:
add link in documentation to former versions

Comments:

Patch:
diff --git a/docs/index.rst b/docs/index.rst
index e121856..c2e3088 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -267,4 +267,5 @@ Table of Contents
    contribute/index
    about/index
    whats_new/index
+   versions/index
    donate
diff --git a/docs/versions/index.rst b/docs/versions/index.rst
new file mode 100644
index 0000000..be193f0
--- /dev/null
+++ b/docs/versions/index.rst
@@ -0,0 +1,12 @@
+Other versions
+==============
+
+Web-based documentation is available for versions listed below:
+
+- `Feature-engine 1.6 <https://feature-engine.trainindata.com/en/1.6.x/index.html>`_
+- `Feature-engine 1.5 <https://feature-engine.trainindata.com/en/1.5.x/index.html>`_
+- `Feature-engine 1.4 <https://feature-engine.trainindata.com/en/1.4.x/index.html>`_
+- `Feature-engine 1.3 <https://feature-engine.trainindata.com/en/1.3.x/index.html>`_
+- `Feature-engine 1.2 <https://feature-engine.trainindata.com/en/1.2.x/index.html>`_
+- `Feature-engine 1.1 <https://feature-engine.trainindata.com/en/1.1.x/index.html>`_
+- `Feature-engine 0.6 <https://feature-engine.trainindata.com/en/0.6.x_a/>`_
diff --git a/feature_engine/encoding/rare_label.py b/feature_engine/encoding/rare_label.py
index 4859b2c..c7afb18 100644
--- a/feature_engine/encoding/rare_label.py
+++ b/feature_engine/encoding/rare_label.py
@@ -218,7 +218,7 @@ class RareLabelEncoder(CategoricalInitMixinNA, CategoricalMethodsMixin):
                     "indicated in n_categories. Thus, all categories will be "
                     "considered frequent".format(var)
                 )
-                self.encoder_dict_[var] = X[var].unique()
+                self.encoder_dict_[var] = list(X[var].unique())
 
         self.variables_ = variables_
         self._get_feature_names_in(X)
@@ -247,19 +247,19 @@ class RareLabelEncoder(CategoricalInitMixinNA, CategoricalMethodsMixin):
             _check_optional_contains_na(X, self.variables_)
 
             for feature in self.variables_:
-                X[feature] = np.where(
-                    X[feature].isin(self.encoder_dict_[feature]),
-                    X[feature],
-                    self.replace_with,
-                )
+                if X[feature].dtype == "category":
+                    X[feature] = X[feature].cat.add_categories(self.replace_with)
+                X.loc[
+                    ~X[feature].isin(self.encoder_dict_[feature]), feature
+                ] = self.replace_with
 
         else:
             for feature in self.variables_:
-                X[feature] = np.where(
-                    X[feature].isin(self.encoder_dict_[feature] + [np.nan]),
-                    X[feature],
-                    self.replace_with,
-                )
+                if X[feature].dtype == "category":
+                    X[feature] = X[feature].cat.add_categories(self.replace_with)
+                X.loc[
+                    ~X[feature].isin(self.encoder_dict_[feature] + [np.nan]), feature
+                ] = self.replace_with
 
         return X
 


Test patch:
diff --git a/tests/test_encoding/test_rare_label_encoder.py b/tests/test_encoding/test_rare_label_encoder.py
index 1a17553..ba85299 100644
--- a/tests/test_encoding/test_rare_label_encoder.py
+++ b/tests/test_encoding/test_rare_label_encoder.py
@@ -54,6 +54,34 @@ def test_defo_params_plus_automatically_find_variables(df_enc_big):
     pd.testing.assert_frame_equal(X, df)
 
 
+def test_when_varnames_are_numbers(df_enc_big):
+    input_df = df_enc_big.copy()
+    input_df.columns = [1, 2, 3]
+
+    encoder = RareLabelEncoder(
+        tol=0.06, n_categories=5, variables=None, replace_with="Rare"
+    )
+    X = encoder.fit_transform(input_df)
+
+    # expected output
+    df = {
+        1: ["A"] * 6 + ["B"] * 10 + ["C"] * 4 + ["D"] * 10 + ["Rare"] * 4 + ["G"] * 6,
+        2: ["A"] * 10 + ["B"] * 6 + ["C"] * 4 + ["D"] * 10 + ["Rare"] * 4 + ["G"] * 6,
+        3: ["A"] * 4 + ["B"] * 6 + ["C"] * 10 + ["D"] * 10 + ["Rare"] * 4 + ["G"] * 6,
+    }
+    df = pd.DataFrame(df)
+
+    frequenc_cat = {
+        1: ["B", "D", "A", "G", "C"],
+        2: ["A", "D", "B", "G", "C"],
+        3: ["C", "D", "B", "G", "A"],
+    }
+
+    assert encoder.variables_ == [1, 2, 3]
+    assert encoder.encoder_dict_ == frequenc_cat
+    pd.testing.assert_frame_equal(X, df)
+
+
 def test_correctly_ignores_nan_in_transform(df_enc_big):
     encoder = RareLabelEncoder(
         tol=0.06,
@@ -102,7 +130,7 @@ def test_correctly_ignores_nan_in_fit(df_enc_big):
         n_categories=3,
         missing_values="ignore",
     )
-    X = encoder.fit_transform(df)
+    encoder.fit(df)
 
     # expected:
     frequenc_cat = {
@@ -134,6 +162,90 @@ def test_correctly_ignores_nan_in_fit(df_enc_big):
     pd.testing.assert_frame_equal(X, tt)
 
 
+def test_correctly_ignores_nan_in_fit_when_var_is_numerical(df_enc_big):
+
+    df = df_enc_big.copy()
+    df["var_C"] = [
+        1,
+        1,
+        1,
+        1,
+        2,
+        2,
+        2,
+        2,
+        2,
+        2,
+        3,
+        3,
+        3,
+        3,
+        3,
+        3,
+        3,
+        3,
+        3,
+        3,
+        4,
+        4,
+        4,
+        4,
+        4,
+        4,
+        4,
+        4,
+        4,
+        4,
+        5,
+        5,
+        6,
+        6,
+        np.nan,
+        np.nan,
+        np.nan,
+        np.nan,
+        np.nan,
+        np.nan,
+    ]
+
+    encoder = RareLabelEncoder(
+        tol=0.06,
+        n_categories=3,
+        missing_values="ignore",
+        ignore_format=True,
+    )
+    encoder.fit(df)
+
+    # expected:
+    frequenc_cat = {
+        "var_A": ["B", "D", "A", "G", "C"],
+        "var_B": ["A", "D", "B", "G", "C"],
+        "var_C": [3, 4, 2, 1],
+    }
+    assert encoder.encoder_dict_ == frequenc_cat
+
+    # input
+    t = pd.DataFrame(
+        {
+            "var_A": ["A", np.nan, "J", "G"],
+            "var_B": ["A", np.nan, "J", "G"],
+            "var_C": [3, np.nan, 9, 10],
+        }
+    )
+
+    # expected
+    tt = pd.DataFrame(
+        {
+            "var_A": ["A", np.nan, "Rare", "G"],
+            "var_B": ["A", np.nan, "Rare", "G"],
+            "var_C": [3.0, np.nan, "Rare", "Rare"],
+        }
+    )
+
+    X = encoder.transform(t)
+    pd.testing.assert_frame_equal(X, tt, check_dtype=False)
+
+
 def test_user_provides_grouping_label_name_and_variable_list(df_enc_big):
     # test case 2: user provides alternative grouping value and variable list
     encoder = RareLabelEncoder(
@@ -316,12 +428,84 @@ def test_variables_cast_as_category(df_enc_big):
         + ["G"] * 6,
     }
     df = pd.DataFrame(df)
+    df["var_B"] = pd.Categorical(df["var_B"])
 
     # test fit attr
     assert encoder.variables_ == ["var_A", "var_B", "var_C"]
     assert encoder.n_features_in_ == 3
     # test transform output
-    pd.testing.assert_frame_equal(X, df)
+    pd.testing.assert_frame_equal(X, df, check_categorical=False)
+
+
+def test_variables_cast_as_category_with_na_in_transform(df_enc_big):
+    encoder = RareLabelEncoder(
+        tol=0.06,
+        n_categories=5,
+        variables=None,
+        replace_with="Rare",
+        missing_values="ignore",
+    )
+
+    df_enc_big = df_enc_big.copy()
+    df_enc_big["var_B"] = df_enc_big["var_B"].astype("category")
+    encoder.fit(df_enc_big)
+
+    # input
+    t = pd.DataFrame(
+        {
+            "var_A": ["A", np.nan, "J", "G"],
+            "var_B": ["A", np.nan, "J", "G"],
+            "var_C": ["A", np.nan, "J", "G"],
+        }
+    )
+    t["var_B"] = pd.Categorical(t["var_B"])
+
+    # expected
+    tt = pd.DataFrame(
+        {
+            "var_A": ["A", np.nan, "Rare", "G"],
+            "var_B": ["A", np.nan, "Rare", "G"],
+            "var_C": ["A", np.nan, "Rare", "G"],
+        }
+    )
+    tt["var_B"] = pd.Categorical(tt["var_B"])
+    pd.testing.assert_frame_equal(encoder.transform(t), tt, check_categorical=False)
+
+
+def test_variables_cast_as_category_with_na_in_fit(df_enc_big):
+
+    df = df_enc_big.copy()
+    df.loc[df["var_C"] == "G", "var_C"] = np.nan
+    df["var_C"] = df["var_C"].astype("category")
+
+    encoder = RareLabelEncoder(
+        tol=0.06,
+        n_categories=3,
+        missing_values="ignore",
+    )
+    encoder.fit(df)
+
+    # input
+    t = pd.DataFrame(
+        {
+            "var_A": ["A", np.nan, "J", "G"],
+            "var_B": ["A", np.nan, "J", "G"],
+            "var_C": ["C", np.nan, "J", "G"],
+        }
+    )
+    t["var_C"] = pd.Categorical(t["var_C"])
+
+    # expected
+    tt = pd.DataFrame(
+        {
+            "var_A": ["A", np.nan, "Rare", "G"],
+            "var_B": ["A", np.nan, "Rare", "G"],
+            "var_C": ["C", np.nan, "Rare", "Rare"],
+        }
+    )
+    tt["var_C"] = pd.Categorical(tt["var_C"])
+
+    pd.testing.assert_frame_equal(encoder.transform(t), tt, check_categorical=False)
 
 
 def test_inverse_transform_raises_not_implemented_error(df_enc_big):