Repository: feature-engine/feature_engine
Pull request #472 (2022-06-12 09:18:39)

udpate python versions in setup py


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 8c0c388..c14af2d 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,7 +2,7 @@ version: 2
 
 defaults: &defaults
   docker:
-    - image: circleci/python:3.8.0
+    - image: circleci/python:3.9.0
   working_directory: ~/project
 
 prepare_tox: &prepare_tox
@@ -57,13 +57,13 @@ jobs:
           path: ~/project
       - *prepare_tox
       - run:
-          name: Run tests with Python 3.9
+          name: Run tests with Python 3.10
           command: |
-            tox -e py39
+            tox -e py310
 
   test_style:
     docker:
-      - image: circleci/python:3.8.0
+      - image: circleci/python:3.9.0
     working_directory: ~/project
     steps:
       - checkout:
@@ -76,7 +76,7 @@ jobs:
 
   test_docs:
     docker:
-      - image: circleci/python:3.8.0
+      - image: circleci/python:3.9.0
     working_directory: ~/project
     steps:
       - checkout:
@@ -89,7 +89,7 @@ jobs:
 
   test_type:
     docker:
-      - image: circleci/python:3.8.0
+      - image: circleci/python:3.9.0
     working_directory: ~/project
     steps:
       - checkout:
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
new file mode 100644
index 0000000..af68429
--- /dev/null
+++ b/docs/_templates/layout.html
@@ -0,0 +1,9 @@
+{%- extends "pydata_sphinx_theme/layout.html" %}
+
+{%- block extrahead %}
+
+{{ super() }}
+
+<script defer data-domain="feature-engine.readthedocs.io" src="https://plausible.io/js/plausible.js"></script>
+
+{% endblock %}
\ No newline at end of file
diff --git a/feature_engine/transformation/boxcox.py b/feature_engine/transformation/boxcox.py
index 60666d6..7638954 100644
--- a/feature_engine/transformation/boxcox.py
+++ b/feature_engine/transformation/boxcox.py
@@ -5,16 +5,20 @@ from typing import List, Optional, Union
 
 import pandas as pd
 import scipy.stats as stats
+from scipy.special import inv_boxcox
 
-from feature_engine.base_transformers import BaseNumericalTransformer
-from feature_engine._docstrings.methods import _fit_transform_docstring
+from feature_engine._docstrings.class_inputs import _variables_numerical_docstring
 from feature_engine._docstrings.fit_attributes import (
-    _variables_attribute_docstring,
     _feature_names_in_docstring,
     _n_features_in_docstring,
+    _variables_attribute_docstring,
+)
+from feature_engine._docstrings.methods import (
+    _fit_transform_docstring,
+    _inverse_transform_docstring,
 )
-from feature_engine._docstrings.class_inputs import _variables_numerical_docstring
 from feature_engine._docstrings.substitute import Substitution
+from feature_engine.base_transformers import BaseNumericalTransformer
 from feature_engine.tags import _return_tags
 from feature_engine.variable_manipulation import _check_input_parameter_variables
 
@@ -25,6 +29,7 @@ from feature_engine.variable_manipulation import _check_input_parameter_variable
     feature_names_in_=_feature_names_in_docstring,
     n_features_in_=_n_features_in_docstring,
     fit_transform=_fit_transform_docstring,
+    inverse_transform=_inverse_transform_docstring,
 )
 class BoxCoxTransformer(BaseNumericalTransformer):
     """
@@ -74,6 +79,8 @@ class BoxCoxTransformer(BaseNumericalTransformer):
 
     {fit_transform}
 
+    {inverse_transform}
+
     transform:
         Apply the BoxCox transformation.
 
@@ -138,6 +145,30 @@ class BoxCoxTransformer(BaseNumericalTransformer):
 
         return X
 
+    def inverse_transform(self, X: pd.DataFrame) -> pd.DataFrame:
+        """
+        Convert the data back to the original representation.
+
+        Parameters
+        ----------
+        X: Pandas DataFrame of shape = [n_samples, n_features]
+            The data to be inverse transformed.
+
+        Returns
+        -------
+        X_new: pandas dataframe
+            The dataframe with the original variables.
+        """
+
+        # check input dataframe and if class was fitted
+        X = super().transform(X)
+
+        # inverse transform
+        for feature in self.variables_:
+            X[feature] = inv_boxcox(X[feature], self.lambda_dict_[feature])
+
+        return X
+
     def _more_tags(self):
         tags_dict = _return_tags()
         tags_dict["variables"] = "numerical"
diff --git a/setup.py b/setup.py
index 96a125c..ac238ff 100644
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@ DESCRIPTION = "Feature engineering package with Scikit-learn's fit transform fun
 URL = "http://github.com/feature-engine/feature_engine"
 EMAIL = "solegalli@protonmail.com"
 AUTHOR = "Soledad Galli"
-REQUIRES_PYTHON = ">=3.6.0"
+REQUIRES_PYTHON = ">=3.8.0"
 
 # description
 with open("README.md", "r") as fh:
@@ -46,11 +46,9 @@ setup(name=NAME,
       classifiers=[
           # Trove classifiers
           # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
-          "License :: OSI Approved :: MIT License",
-          "Programming Language :: Python",
-          "Programming Language :: Python :: 3",
-          "Programming Language :: Python :: 3.6",
-          "Programming Language :: Python :: 3.7",
+          "License :: OSI Approved :: BSD License",
           "Programming Language :: Python :: 3.8",
+          "Programming Language :: Python :: 3.9",
+          "Programming Language :: Python :: 3.10",
       ],
       zip_safe=False)
diff --git a/tox.ini b/tox.ini
index 37cf66a..caec17d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py37, py38, py39, docs, lint, stylechecks, typechecks
+envlist = py38, py39, py310, docs, stylechecks, typechecks
 skipsdist = true
 
 [testenv]
@@ -13,16 +13,15 @@ commands =
     pytest tests
 
 
-[testenv:py37]
+[testenv:py38]
 deps =
     -rtest_requirements.txt
 
-
-[testenv:py38]
+[testenv:py39]
 deps =
     -rtest_requirements.txt
 
-[testenv:py39]
+[testenv:py310]
 deps =
     -rtest_requirements.txt
 
@@ -46,22 +45,13 @@ deps =
 
 commands = {posargs:mypy feature_engine}
 
-[testenv:lint]
-deps =
-	-rtest_requirements.txt
-
-commands =
-	isort feature_engine tests
-	black feature_engine tests
-
 
 [flake8]
 exclude = .git, env
 # match black code formatter
 max-line-length = 88
 
-[isort]
-skip =  feature_engine/outliers/__init__.py
+
 profile = black
 line_length = 88
 lines_between_sections = 1


Test patch:
diff --git a/tests/test_transformation/test_boxcox_transformer.py b/tests/test_transformation/test_boxcox_transformer.py
index 03b1184..1681402 100644
--- a/tests/test_transformation/test_boxcox_transformer.py
+++ b/tests/test_transformation/test_boxcox_transformer.py
@@ -23,6 +23,16 @@ def test_automatically_finds_variables(df_vartypes):
     # test transform output
     pd.testing.assert_frame_equal(X, transf_df)
 
+    # test inverse_transform
+    Xit = transformer.inverse_transform(X)
+
+    # convert numbers to original format.
+    Xit["Age"] = Xit["Age"].round().astype("int64")
+    Xit["Marks"] = Xit["Marks"].round(1)
+
+    # test
+    pd.testing.assert_frame_equal(Xit, df_vartypes)
+
 
 def test_fit_raises_error_if_df_contains_na(df_na):
     # test case 2: when dataset contains na, fit method