Repository: KIT-IAI/pyWATTS

Issue:
Store NPY Data.
Implement a NPYCallback

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fbcaf3..f57f7fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@
 * Add a module to insert unusual behaviour into a time series ([#240](https://github.com/KIT-IAI/pyWATTS/issues/240))
 * Add F1Score Summary ([#234](https://github.com/KIT-IAI/pyWATTS/issues/234))
 * Add a discriminative score summary ([#238](https://github.com/KIT-IAI/pyWATTS/issues/238))
+* Add NPY Callback ([#247](https://github.com/KIT-IAI/pyWATTS/issues/247))
 
 ### Changed
 * Make the inputs of the PNN more flexible ([#228](https://github.com/KIT-IAI/pyWATTS/issues/228))
diff --git a/pywatts/callbacks/__init__.py b/pywatts/callbacks/__init__.py
index 3608e77..d2a4bc4 100644
--- a/pywatts/callbacks/__init__.py
+++ b/pywatts/callbacks/__init__.py
@@ -2,4 +2,5 @@ from pywatts.callbacks.base_callback import BaseCallback
 from pywatts.callbacks.csv_callback import CSVCallback
 from pywatts.callbacks.debug_callback import PrintCallback, StatisticCallback
 from pywatts.callbacks.plot_callback import ImagePlotCallback, LinePlotCallback
+from pywatts.callbacks.npy_callback import NPYCallback
 
diff --git a/pywatts/callbacks/npy_callback.py b/pywatts/callbacks/npy_callback.py
new file mode 100644
index 0000000..dcce883
--- /dev/null
+++ b/pywatts/callbacks/npy_callback.py
@@ -0,0 +1,42 @@
+from typing import Optional
+
+import xarray as xr
+import numpy as np
+
+import matplotlib.pyplot as plt
+
+from pywatts.callbacks.base_callback import BaseCallback
+
+
+class NPYCallback(BaseCallback):
+    """
+    Callback to save the data as npy file.
+    """
+
+    def __init__(self, prefix: str, use_filemanager: Optional[bool] = None):
+        """
+        Initialise NPYCallback given a filename and
+        optional use_filemanager flag.
+
+        :param prefix: Prefix to use for the stored file.
+        :type prefix: str
+        :param use_filemanager: Flag to denote if the filemanager of the pipeline should be used.
+        :type use_filemanager: Optional[bool]
+        """
+        if use_filemanager is None:
+            # use base class default if use_filemanager is not set
+            super().__init__()
+        else:
+            super().__init__(use_filemanager)
+        self.prefix = prefix
+
+    def __call__(self, data_dict: xr.DataArray):
+        """
+        Implementation of abstract __call__ base method to store the npy file.
+
+        :param data_dict: Dict of DataArrays that should be stored as npy file.
+        :type data_dict: Dict[str, xr.DataArray]
+        """
+        for key in data_dict:
+            with open(self.get_path(f"{self.prefix}_{key}.npy"), "wb") as file:
+                np.save(file, data_dict[key].values)
diff --git a/pywatts/core/filemanager.py b/pywatts/core/filemanager.py
index 6662737..76ab95f 100644
--- a/pywatts/core/filemanager.py
+++ b/pywatts/core/filemanager.py
@@ -7,7 +7,7 @@ from pywatts.core.exceptions.io_exceptions import IOException
 
 logger = logging.getLogger()
 
-ALLOWED_FILES = ["png", "csv", "xlsx", "pickle", "tex", "json", "h5", "pt", "md"]
+ALLOWED_FILES = ["png", "csv", "xlsx", "pickle", "tex", "json", "h5", "pt", "md", "npy"]
 
 
 class FileManager:
diff --git a/pywatts/modules/preprocessing/change_direction.py b/pywatts/modules/preprocessing/change_direction.py
index 310bdb9..083496b 100644
--- a/pywatts/modules/preprocessing/change_direction.py
+++ b/pywatts/modules/preprocessing/change_direction.py
@@ -5,7 +5,7 @@ import xarray as xr
 from pywatts.core.base import BaseTransformer
 from pywatts.core.exceptions.wrong_parameter_exception import WrongParameterException
 from pywatts.utils._xarray_time_series_utils import _get_time_indexes
-
+import numpy as np
 
 class ChangeDirection(BaseTransformer):
     """
@@ -45,7 +45,7 @@ class ChangeDirection(BaseTransformer):
         """
         indexes = _get_time_indexes(x)
         try:
-            return xr.ufuncs.sign(x - x.shift({index: 1 for index in indexes}))
+            return xr.apply_ufunc(np.sign, x - x.shift({index: 1 for index in indexes}))
         except ValueError as exc:
             raise WrongParameterException(
                 f"Not all indexes ({indexes}) are in the indexes of x ({list(x.indexes.keys())}).",


Test patch:
diff --git a/tests/unit/core/test_filemanager.py b/tests/unit/core/test_filemanager.py
index f9f24ad..620249d 100644
--- a/tests/unit/core/test_filemanager.py
+++ b/tests/unit/core/test_filemanager.py
@@ -63,7 +63,7 @@ class TestFilemanager(unittest.TestCase):
             self.filemanager.get_path("result.test")
         self.assertEqual(cm.exception.args,
                          ("test is not an allowed file type. Allowed types are ['png', 'csv', 'xlsx', "
-                          "'pickle', 'tex', 'json', 'h5', 'pt', 'md'].",))
+                          "'pickle', 'tex', 'json', 'h5', 'pt', 'md', 'npy'].",))
 
     @patch("pywatts.core.filemanager.logger")
     @patch("pywatts.core.filemanager.datetime")