Repository: blue-yonder/tsfresh

Issue:
underscore not allowed in time series kind names
there is a bug in tsfresh.feature_extraction.settings.from_columns which causes it to raise an error.

If the name of time series column ends with `_`, e.g. `temeprature_valve_`,  you get such an error:

```
ValueError                                Traceback (most recent call last)
<ipython-input-79-9e22830f8581> in <module>
---> 12 kind_to_fc_parameters = tsfresh.feature_extraction.settings.from_columns(nan_in_cols.transpose().columns)

/opt/anaconda/anaconda3/envs/MLEP/lib/python3.6/site-packages/tsfresh/feature_extraction/settings.py in from_columns(columns, columns_to_ignore)
     65 
     66         if not hasattr(feature_calculators, feature_name):
---> 67             raise ValueError("Unknown feature name {}".format(feature_name))
     68 
     69         config = get_config_from_string(parts)

ValueError: Unknown feature name _agg_linear_trend
```

Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/27032390/badge)](https://coveralls.io/builds/27032390)

Coverage remained the same at ?% when pulling **a1410bf77a2d95a98c046002c307cf74b1e5539e on feature/548-check-for-double-underscores** into **e6f5d3eb0cdc8c307a8781a839b5c05da29e8f06 on master**.


Patch:
diff --git a/setup.py b/setup.py
index be4e01e..9022dc0 100644
--- a/setup.py
+++ b/setup.py
@@ -25,6 +25,6 @@ setup(
     long_description=long_description,
     long_description_content_type="text/markdown",
     setup_requires=["six", "setuptools_scm"] + sphinx,
-    packages=find_packages(),
+    packages=find_packages(exclude=["tests.*", "tests"]),
     install_requires=requirements,
 )
diff --git a/tsfresh/utilities/dataframe_functions.py b/tsfresh/utilities/dataframe_functions.py
index 8d9a59c..8f507da 100644
--- a/tsfresh/utilities/dataframe_functions.py
+++ b/tsfresh/utilities/dataframe_functions.py
@@ -354,6 +354,14 @@ def _normalize_input_to_internal_representation(timeseries_container, column_id,
     # The kind columns should always be of type "str" to make the inference of feature settings later in `from_columns`
     # work
     timeseries_container[column_kind] = timeseries_container[column_kind].astype(str)
+
+    # Make sure we have only parsable names
+    for kind in timeseries_container[column_kind].unique():
+        if kind.endswith("_"):
+            raise ValueError("The kind {kind} is not allowed to end with '_'".format(kind=kind))
+        if "__" in kind:
+            raise ValueError("The kind {kind} is not allowed to contain '__'".format(kind=kind))
+
     return timeseries_container, column_id, column_kind, column_value
 
 


Test patch:
diff --git a/tests/units/utilities/test_dataframe_functions.py b/tests/units/utilities/test_dataframe_functions.py
index 8181a97..2d0f8bb 100644
--- a/tests/units/utilities/test_dataframe_functions.py
+++ b/tests/units/utilities/test_dataframe_functions.py
@@ -138,6 +138,12 @@ class NormalizeTestCase(TestCase):
         self.assertRaises(ValueError, dataframe_functions._normalize_input_to_internal_representation, test_df,
                           None, None, None, "value")
 
+        test_df = pd.DataFrame([{"id": 0, "a_": 3, "b": 5, "sort": 1}])
+        self.assertRaises(ValueError, dataframe_functions._normalize_input_to_internal_representation, test_df, "id", "sort", None, None)
+
+        test_df = pd.DataFrame([{"id": 0, "a__c": 3, "b": 5, "sort": 1}])
+        self.assertRaises(ValueError, dataframe_functions._normalize_input_to_internal_representation, test_df, "id", "sort", None, None)
+        
         test_df = pd.DataFrame([{"id": 0}])
         self.assertRaises(ValueError, dataframe_functions._normalize_input_to_internal_representation, test_df,
                           "id", None, None, None)