Repository: andersbogsnes/ml_tooling

Issue:
ENH: Datasets should have a way of listing available features
**Is your feature request related to a problem? Please describe.**
When doing EDA, it would be useful to have a way to describe what features are available

**Describe the solution you'd like**
Having a `.features` attribute that shows what features are available on the dataset

**Describe alternatives you've considered**
What other functionality apart from listing the feature names would be relevant to display? 
Can we use this with feature selection to create feature masks?


Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683?src=pr&el=h1) Report
> Merging [#683](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683?src=pr&el=desc) into [develop](https://codecov.io/gh/andersbogsnes/ml_tooling/commit/18e5b480bea980347fde64ccbdb81b00dcc04232?el=desc) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/graphs/tree.svg?width=650&height=150&src=pr&token=ucKtL3BlxO)](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           develop      #683    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files           55        63     +8     
  Lines         1424      1687   +263     
  Branches       166       190    +24     
==========================================
+ Hits          1424      1687   +263     
```


| [Impacted Files](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/ml\_tooling/plots/utils.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvcGxvdHMvdXRpbHMucHk=) | `100.00% <ø> (ø)` | |
| [src/ml\_tooling/transformers/binner.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvdHJhbnNmb3JtZXJzL2Jpbm5lci5weQ==) | `100.00% <ø> (ø)` | |
| [src/ml\_tooling/transformers/feature\_union.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvdHJhbnNmb3JtZXJzL2ZlYXR1cmVfdW5pb24ucHk=) | `100.00% <ø> (ø)` | |
| [src/ml\_tooling/transformers/renamer.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvdHJhbnNmb3JtZXJzL3JlbmFtZXIucHk=) | `100.00% <ø> (ø)` | |
| [src/ml\_tooling/transformers/to\_categorical.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvdHJhbnNmb3JtZXJzL3RvX2NhdGVnb3JpY2FsLnB5) | `100.00% <ø> (ø)` | |
| [src/ml\_tooling/\_\_init\_\_.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvX19pbml0X18ucHk=) | `100.00% <100.00%> (ø)` | |
| [src/ml\_tooling/baseclass.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvYmFzZWNsYXNzLnB5) | `100.00% <100.00%> (ø)` | |
| [src/ml\_tooling/config.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvY29uZmlnLnB5) | `100.00% <100.00%> (ø)` | |
| [src/ml\_tooling/data/\_\_init\_\_.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvZGF0YS9fX2luaXRfXy5weQ==) | `100.00% <100.00%> (ø)` | |
| [src/ml\_tooling/data/base\_data.py](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree#diff-c3JjL21sX3Rvb2xpbmcvZGF0YS9iYXNlX2RhdGEucHk=) | `100.00% <100.00%> (ø)` | |
| ... and [48 more](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683?src=pr&el=footer). Last update [c7c2012...dd29e7a](https://codecov.io/gh/andersbogsnes/ml_tooling/pull/683?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8310c3d..6b95b1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# v.0.12.1
+- Dataset features can now be easily accessed with the property dataset.features
+
 # v0.12.0
 - Permutation importance and Feature importance are now two different plotting methods.
 - `Model.test_estimators` now takes a `feature_pipeline` argument
diff --git a/src/ml_tooling/data/base_data.py b/src/ml_tooling/data/base_data.py
index ce93934..551e91d 100644
--- a/src/ml_tooling/data/base_data.py
+++ b/src/ml_tooling/data/base_data.py
@@ -113,6 +113,10 @@ class Dataset(metaclass=abc.ABCMeta):
 
         return x, y
 
+    @property
+    def features(self):
+        return self.x.columns.tolist()
+
     def _load_prediction_data(self, *args, **kwargs) -> pd.DataFrame:
         pred_data = self.load_prediction_data(*args, **kwargs)
         if pred_data.empty:


Test patch:
diff --git a/tests/test_datasets/test_dataset.py b/tests/test_datasets/test_dataset.py
index 0e8b0bd..f15e3d3 100644
--- a/tests/test_datasets/test_dataset.py
+++ b/tests/test_datasets/test_dataset.py
@@ -10,6 +10,15 @@ class TestDataset:
         result = str(iris_dataset())
         assert result == "<IrisData - Dataset>"
 
+    def test_feature_names_access_works_correctly(self, iris_dataset):
+        dataset = iris_dataset()
+        assert dataset.features == [
+            "sepal length (cm)",
+            "sepal width (cm)",
+            "petal length (cm)",
+            "petal width (cm)",
+        ]
+
     def test_dataset_x_attribute_access_works_correctly(self, iris_dataset):
         dataset = iris_dataset()
         assert dataset._x is None