We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
TypeError: PandasDataset() takes no arguments for PandasDataset.from_long_dataframe
Following as described in https://ts.gluon.ai/stable/tutorials/data_manipulation/pandasdataframes.html#Use-case-3---Loading-data-with-missing-values I could not get it to work with my own DF nor the example given:

```
ds = PandasDataset.from_long_dataframe(df, target="target", item_id="item_id")
Traceback (most recent call last):

  File "C:\\AppData\Local\Temp/ipykernel_33648/388385624.py", line 1, in <module>
    ds = PandasDataset.from_long_dataframe(dfx, target="target", item_id="item_id")

  File "C:\\Anaconda3\lib\site-packages\gluonts\dataset\pandas.py", line 182, in from_long_dataframe
    return cls(dataframes=dict(list(dataframe.groupby(item_id))), **kwargs)

TypeError: PandasDataset() takes no arguments
```

Also wanted to know if there are any plans of adding a methodology to achieve the same result starting from a wide DF, but (unlike the wide df example) incorporating a way to pass a list of feat_dynamic_cat, feat_static_cat, and so on (in same shape as the width of the wide df).



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/gluonts/dataset/pandas.py`
Content:
```
1 # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License").
4 # You may not use this file except in compliance with the License.
5 # A copy of the License is located at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # or in the "license" file accompanying this file. This file is distributed
10 # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 # express or implied. See the License for the specific language governing
12 # permissions and limitations under the License.
13 
14 from copy import deepcopy
15 from dataclasses import dataclass, field
16 from typing import Any, cast, Dict, Iterator, List, Optional, Union
17 
18 import pandas as pd
19 from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin
20 from toolz import valmap
21 
22 from gluonts.dataset.common import Dataset, DataEntry, ProcessDataEntry
23 from gluonts.dataset.field_names import FieldName
24 
25 
26 @dataclass
27 class PandasDataset(Dataset):
28     """
29     A pandas.DataFrame-based dataset type.
30 
31     This class is constructed with a collection of pandas.DataFrame-objects
32     where each ``DataFrame`` is representing one time series.
33     A ``target`` and a ``timestamp`` columns are essential. Furthermore,
34     static/dynamic real/categorical features can be specified.
35 
36     Parameters
37     ----------
38     dataframes
39         Single ``pd.DataFrame``/``pd.Series`` or a collection as list or dict
40         containing at least ``timestamp`` and ``target`` values.
41         If a Dict is provided, the key will be the associated ``item_id``.
42     target
43         Name of the column that contains the ``target`` time series.
44         For multivariate targets, a list of column names should be provided.
45     timestamp
46         Name of the column that contains the timestamp information.
47     freq
48         Frequency of observations in the time series. Must be a valid pandas
49         frequency.
50     feat_dynamic_real
51         List of column names that contain dynamic real features.
52     feat_dynamic_cat
53         List of column names that contain dynamic categorical features.
54     feat_static_real
55         List of column names that contain static real features.
56     feat_static_cat
57         List of column names that contain static categorical features.
58     past_feat_dynamic_real
59         List of column names that contain dynamic real features only for the
60         history.
61     ignore_last_n_targets
62         For target and past dynamic features last ``ignore_last_n_targets``
63         elements are removed when iterating over the data set. This becomes
64         important when the predictor is called.
65     """
66 
67     dataframes: Union[
68         pd.DataFrame,
69         pd.Series,
70         List[pd.DataFrame],
71         List[pd.Series],
72         Dict[str, pd.DataFrame],
73         Dict[str, pd.Series],
74     ]
75     target: Union[str, List[str]] = "target"
76     timestamp: Optional[str] = None
77     freq: Optional[str] = None
78     feat_dynamic_real: List[str] = field(default_factory=list)
79     feat_dynamic_cat: List[str] = field(default_factory=list)
80     feat_static_real: List[str] = field(default_factory=list)
81     feat_static_cat: List[str] = field(default_factory=list)
82     past_feat_dynamic_real: List[str] = field(default_factory=list)
83     ignore_last_n_targets: int = 0
84 
85     def __post_init__(self) -> None:
86         if isinstance(self.target, list) and len(self.target) == 1:
87             self.target = self.target[0]
88         self.one_dim_target = not isinstance(self.target, list)
89 
90         if is_series(self.dataframes):
91             self.dataframes = series_to_dataframe(self.dataframes)
92         # store data internally as List[Tuple[str, pandas.DataFrame]]
93         # if str is not empty it will be set in ``DataEntry`` as ``item_id``.
94         if isinstance(self.dataframes, dict):
95             self._dataframes = list(self.dataframes.items())
96         elif isinstance(self.dataframes, list):
97             self._dataframes = [(None, df) for df in self.dataframes]
98         else:  # case single dataframe
99             self._dataframes = [(None, self.dataframes)]
100 
101         for i, (item_id, df) in enumerate(self._dataframes):
102             if self.timestamp:
103                 df = df.set_index(keys=self.timestamp)
104 
105             if not isinstance(df.index, pd.PeriodIndex):
106                 df.index = pd.to_datetime(df.index)
107                 df = df.to_period(freq=self.freq)
108 
109             df.sort_index(inplace=True)
110 
111             assert is_uniform(df.index), (
112                 "Dataframe index is not uniformly spaced. "
113                 "If your dataframe contains data from multiple series in the "
114                 'same column ("long" format), consider constructing the '
115                 "dataset with `PandasDataset.from_long_dataframe` instead."
116             )
117 
118             self._dataframes[i] = (item_id, df)
119 
120         if not self.freq:  # infer frequency from index
121             self.freq = self._dataframes[0][1].index.freqstr
122 
123         self.process = ProcessDataEntry(
124             cast(str, self.freq), one_dim_target=self.one_dim_target
125         )
126 
127     def _dataentry(
128         self, item_id: Optional[str], df: pd.DataFrame
129     ) -> DataEntry:
130         dataentry = as_dataentry(
131             data=df,
132             target=self.target,
133             feat_dynamic_real=self.feat_dynamic_real,
134             feat_dynamic_cat=self.feat_dynamic_cat,
135             feat_static_real=self.feat_static_real,
136             feat_static_cat=self.feat_static_cat,
137             past_feat_dynamic_real=self.past_feat_dynamic_real,
138         )
139         if item_id is not None:
140             dataentry["item_id"] = item_id
141         return dataentry
142 
143     def __iter__(self) -> Iterator[DataEntry]:
144         for item_id, df in self._dataframes:
145             dataentry = self.process(self._dataentry(item_id, df))
146             if self.ignore_last_n_targets:
147                 dataentry = prepare_prediction_data(
148                     dataentry, self.ignore_last_n_targets
149                 )
150             yield dataentry
151 
152     def __len__(self) -> int:
153         return len(self._dataframes)
154 
155     @classmethod
156     def from_long_dataframe(
157         cls, dataframe: pd.DataFrame, item_id: str, **kwargs
158     ) -> "PandasDataset":
159         """
160         Construct ``PandasDataset`` out of a long dataframe.
161         A long dataframe uses the long format for each variable. Target time
162         series values, for example, are stacked on top of each other rather
163         than side-by-side. The same is true for other dynamic or categorical
164         features.
165 
166         Parameters
167         ----------
168         dataframe
169             pandas.DataFrame containing at least ``timestamp``, ``target`` and
170             ``item_id`` columns.
171         item_id
172             Name of the column that, when grouped by, gives the different time
173             series.
174         **kwargs
175             Additional arguments. Same as of PandasDataset class.
176 
177         Returns
178         -------
179         PandasDataset
180             Gluonts dataset based on ``pandas.DataFrame``s.
181         """
182         return cls(dataframes=dict(list(dataframe.groupby(item_id))), **kwargs)
183 
184 
185 def series_to_dataframe(
186     series: Union[pd.Series, List[pd.Series], Dict[str, pd.Series]]
187 ) -> Union[pd.DataFrame, List[pd.DataFrame], Dict[str, pd.DataFrame]]:
188     def to_df(series):
189         assert isinstance(
190             series.index, DatetimeIndexOpsMixin
191         ), "series index has to be a DatetimeIndex."
192         return series.to_frame(name="target")
193 
194     if isinstance(series, list):
195         return list(map(to_df, series))
196     elif isinstance(series, dict):
197         return valmap(to_df, series)
198     return to_df(series)
199 
200 
201 def is_series(series: Any) -> bool:
202     """
203     return True if ``series`` is ``pd.Series`` or a collection of
204     ``pd.Series``.
205     """
206     if isinstance(series, list):
207         return is_series(series[0])
208     elif isinstance(series, dict):
209         return is_series(list(series.values()))
210     return isinstance(series, pd.Series)
211 
212 
213 def as_dataentry(
214     data: pd.DataFrame,
215     target: Union[str, List[str]],
216     timestamp: Optional[str] = None,
217     feat_dynamic_real: List[str] = [],
218     feat_dynamic_cat: List[str] = [],
219     feat_static_real: List[str] = [],
220     feat_static_cat: List[str] = [],
221     past_feat_dynamic_real: List[str] = [],
222 ) -> DataEntry:
223     """
224     Convert a single time series (uni- or multi-variate) that is given in
225     a pandas.DataFrame format to a DataEntry.
226 
227     Parameters
228     ----------
229     data
230         pandas.DataFrame containing at least ``timestamp``, ``target`` and
231         ``item_id`` columns.
232     target
233         Name of the column that contains the ``target`` time series.
234         For multivariate targets ``target`` is expecting a list of column
235         names.
236     timestamp
237         Name of the column that contains the timestamp information.
238         If ``None`` the index of ``data`` is assumed to be the time.
239     feat_dynamic_real
240         List of column names that contain dynamic real features.
241     feat_dynamic_cat
242         List of column names that contain dynamic categorical features.
243     feat_static_real
244         List of column names that contain static real features.
245     feat_static_cat
246         List of column names that contain static categorical features.
247     past_feat_dynamic_real
248         List of column names that contain dynamic real features only for
249         the history.
250 
251     Returns
252     -------
253     DataEntry
254         A dictionary with at least ``target`` and ``start`` field.
255     """
256     start = data.loc[:, timestamp].iloc[0] if timestamp else data.index[0]
257     dataentry = {FieldName.START: start}
258 
259     def set_field(fieldname, col_names, f=lambda x: x):
260         if col_names:
261             dataentry[fieldname] = [
262                 f(data.loc[:, n].to_list()) for n in col_names
263             ]
264 
265     if isinstance(target, str):
266         dataentry[FieldName.TARGET] = data.loc[:, target].to_list()
267     else:
268         set_field(FieldName.TARGET, target)
269     set_field(FieldName.FEAT_DYNAMIC_REAL, feat_dynamic_real)
270     set_field(FieldName.FEAT_DYNAMIC_CAT, feat_dynamic_cat)
271     set_field(FieldName.FEAT_STATIC_REAL, feat_static_real, lambda x: x[0])
272     set_field(FieldName.FEAT_STATIC_CAT, feat_static_cat, lambda x: x[0])
273     set_field(FieldName.PAST_FEAT_DYNAMIC_REAL, past_feat_dynamic_real)
274     return dataentry
275 
276 
277 def prepare_prediction_data(
278     dataentry: DataEntry, ignore_last_n_targets: int
279 ) -> DataEntry:
280     """
281     Remove ``ignore_last_n_targets`` values from ``target`` and
282     ``past_feat_dynamic_real``.  Works in univariate and multivariate case.
283 
284     >>> prepare_prediction_data(
285     >>>    {"target": np.array([1., 2., 3., 4.])}, ignore_last_n_targets=2
286     >>> )
287     {'target': array([1., 2.])}
288     """
289     entry = deepcopy(dataentry)
290     for fname in [FieldName.TARGET, FieldName.PAST_FEAT_DYNAMIC_REAL]:
291         if fname in entry:
292             entry[fname] = entry[fname][..., :-ignore_last_n_targets]
293     return entry
294 
295 
296 def is_uniform(index: pd.PeriodIndex) -> bool:
297     """
298     Check if ``index`` contains monotonically increasing periods, evenly spaced
299     with frequency ``index.freq``.
300 
301     >>> ts = ["2021-01-01 00:00", "2021-01-01 02:00", "2021-01-01 04:00"]
302     >>> is_uniform(pd.DatetimeIndex(ts).to_period("2H"))
303     True
304     >>> ts = ["2021-01-01 00:00", "2021-01-01 04:00"]
305     >>> is_uniform(pd.DatetimeIndex(ts).to_period("2H"))
306     False
307     """
308     return (index[1:] - index[:-1] == index.freq).all()
309
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/gluonts/dataset/pandas.py b/src/gluonts/dataset/pandas.py
--- a/src/gluonts/dataset/pandas.py
+++ b/src/gluonts/dataset/pandas.py
@@ -19,12 +19,12 @@
 from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin
 from toolz import valmap
 
-from gluonts.dataset.common import Dataset, DataEntry, ProcessDataEntry
+from gluonts.dataset.common import DataEntry, ProcessDataEntry
 from gluonts.dataset.field_names import FieldName
 
 
 @dataclass
-class PandasDataset(Dataset):
+class PandasDataset:
     """
     A pandas.DataFrame-based dataset type.

{"golden_diff": "diff --git a/src/gluonts/dataset/pandas.py b/src/gluonts/dataset/pandas.py\n--- a/src/gluonts/dataset/pandas.py\n+++ b/src/gluonts/dataset/pandas.py\n@@ -19,12 +19,12 @@\n from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin\n from toolz import valmap\n \n-from gluonts.dataset.common import Dataset, DataEntry, ProcessDataEntry\n+from gluonts.dataset.common import DataEntry, ProcessDataEntry\n from gluonts.dataset.field_names import FieldName\n \n \n @dataclass\n-class PandasDataset(Dataset):\n+class PandasDataset:\n     \"\"\"\n     A pandas.DataFrame-based dataset type.\n", "issue": "TypeError: PandasDataset() takes no arguments for PandasDataset.from_long_dataframe\nFollowing as described in https://ts.gluon.ai/stable/tutorials/data_manipulation/pandasdataframes.html#Use-case-3---Loading-data-with-missing-values I could not get it to work with my own DF nor the example given:\r\n\r\n```\r\nds = PandasDataset.from_long_dataframe(df, target=\"target\", item_id=\"item_id\")\r\nTraceback (most recent call last):\r\n\r\n  File \"C:\\\\AppData\\Local\\Temp/ipykernel_33648/388385624.py\", line 1, in <module>\r\n    ds = PandasDataset.from_long_dataframe(dfx, target=\"target\", item_id=\"item_id\")\r\n\r\n  File \"C:\\\\Anaconda3\\lib\\site-packages\\gluonts\\dataset\\pandas.py\", line 182, in from_long_dataframe\r\n    return cls(dataframes=dict(list(dataframe.groupby(item_id))), **kwargs)\r\n\r\nTypeError: PandasDataset() takes no arguments\r\n```\r\n\r\nAlso wanted to know if there are any plans of adding a methodology to achieve the same result starting from a wide DF, but (unlike the wide df example) incorporating a way to pass a list of feat_dynamic_cat, feat_static_cat, and so on (in same shape as the width of the wide df).\r\n\r\n\n", "before_files": [{"content": "# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\").\n# You may not use this file except in compliance with the License.\n# A copy of the License is located at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# or in the \"license\" file accompanying this file. This file is distributed\n# on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n# express or implied. See the License for the specific language governing\n# permissions and limitations under the License.\n\nfrom copy import deepcopy\nfrom dataclasses import dataclass, field\nfrom typing import Any, cast, Dict, Iterator, List, Optional, Union\n\nimport pandas as pd\nfrom pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin\nfrom toolz import valmap\n\nfrom gluonts.dataset.common import Dataset, DataEntry, ProcessDataEntry\nfrom gluonts.dataset.field_names import FieldName\n\n\n@dataclass\nclass PandasDataset(Dataset):\n    \"\"\"\n    A pandas.DataFrame-based dataset type.\n\n    This class is constructed with a collection of pandas.DataFrame-objects\n    where each ``DataFrame`` is representing one time series.\n    A ``target`` and a ``timestamp`` columns are essential. Furthermore,\n    static/dynamic real/categorical features can be specified.\n\n    Parameters\n    ----------\n    dataframes\n        Single ``pd.DataFrame``/``pd.Series`` or a collection as list or dict\n        containing at least ``timestamp`` and ``target`` values.\n        If a Dict is provided, the key will be the associated ``item_id``.\n    target\n        Name of the column that contains the ``target`` time series.\n        For multivariate targets, a list of column names should be provided.\n    timestamp\n        Name of the column that contains the timestamp information.\n    freq\n        Frequency of observations in the time series. Must be a valid pandas\n        frequency.\n    feat_dynamic_real\n        List of column names that contain dynamic real features.\n    feat_dynamic_cat\n        List of column names that contain dynamic categorical features.\n    feat_static_real\n        List of column names that contain static real features.\n    feat_static_cat\n        List of column names that contain static categorical features.\n    past_feat_dynamic_real\n        List of column names that contain dynamic real features only for the\n        history.\n    ignore_last_n_targets\n        For target and past dynamic features last ``ignore_last_n_targets``\n        elements are removed when iterating over the data set. This becomes\n        important when the predictor is called.\n    \"\"\"\n\n    dataframes: Union[\n        pd.DataFrame,\n        pd.Series,\n        List[pd.DataFrame],\n        List[pd.Series],\n        Dict[str, pd.DataFrame],\n        Dict[str, pd.Series],\n    ]\n    target: Union[str, List[str]] = \"target\"\n    timestamp: Optional[str] = None\n    freq: Optional[str] = None\n    feat_dynamic_real: List[str] = field(default_factory=list)\n    feat_dynamic_cat: List[str] = field(default_factory=list)\n    feat_static_real: List[str] = field(default_factory=list)\n    feat_static_cat: List[str] = field(default_factory=list)\n    past_feat_dynamic_real: List[str] = field(default_factory=list)\n    ignore_last_n_targets: int = 0\n\n    def __post_init__(self) -> None:\n        if isinstance(self.target, list) and len(self.target) == 1:\n            self.target = self.target[0]\n        self.one_dim_target = not isinstance(self.target, list)\n\n        if is_series(self.dataframes):\n            self.dataframes = series_to_dataframe(self.dataframes)\n        # store data internally as List[Tuple[str, pandas.DataFrame]]\n        # if str is not empty it will be set in ``DataEntry`` as ``item_id``.\n        if isinstance(self.dataframes, dict):\n            self._dataframes = list(self.dataframes.items())\n        elif isinstance(self.dataframes, list):\n            self._dataframes = [(None, df) for df in self.dataframes]\n        else:  # case single dataframe\n            self._dataframes = [(None, self.dataframes)]\n\n        for i, (item_id, df) in enumerate(self._dataframes):\n            if self.timestamp:\n                df = df.set_index(keys=self.timestamp)\n\n            if not isinstance(df.index, pd.PeriodIndex):\n                df.index = pd.to_datetime(df.index)\n                df = df.to_period(freq=self.freq)\n\n            df.sort_index(inplace=True)\n\n            assert is_uniform(df.index), (\n                \"Dataframe index is not uniformly spaced. \"\n                \"If your dataframe contains data from multiple series in the \"\n                'same column (\"long\" format), consider constructing the '\n                \"dataset with `PandasDataset.from_long_dataframe` instead.\"\n            )\n\n            self._dataframes[i] = (item_id, df)\n\n        if not self.freq:  # infer frequency from index\n            self.freq = self._dataframes[0][1].index.freqstr\n\n        self.process = ProcessDataEntry(\n            cast(str, self.freq), one_dim_target=self.one_dim_target\n        )\n\n    def _dataentry(\n        self, item_id: Optional[str], df: pd.DataFrame\n    ) -> DataEntry:\n        dataentry = as_dataentry(\n            data=df,\n            target=self.target,\n            feat_dynamic_real=self.feat_dynamic_real,\n            feat_dynamic_cat=self.feat_dynamic_cat,\n            feat_static_real=self.feat_static_real,\n            feat_static_cat=self.feat_static_cat,\n            past_feat_dynamic_real=self.past_feat_dynamic_real,\n        )\n        if item_id is not None:\n            dataentry[\"item_id\"] = item_id\n        return dataentry\n\n    def __iter__(self) -> Iterator[DataEntry]:\n        for item_id, df in self._dataframes:\n            dataentry = self.process(self._dataentry(item_id, df))\n            if self.ignore_last_n_targets:\n                dataentry = prepare_prediction_data(\n                    dataentry, self.ignore_last_n_targets\n                )\n            yield dataentry\n\n    def __len__(self) -> int:\n        return len(self._dataframes)\n\n    @classmethod\n    def from_long_dataframe(\n        cls, dataframe: pd.DataFrame, item_id: str, **kwargs\n    ) -> \"PandasDataset\":\n        \"\"\"\n        Construct ``PandasDataset`` out of a long dataframe.\n        A long dataframe uses the long format for each variable. Target time\n        series values, for example, are stacked on top of each other rather\n        than side-by-side. The same is true for other dynamic or categorical\n        features.\n\n        Parameters\n        ----------\n        dataframe\n            pandas.DataFrame containing at least ``timestamp``, ``target`` and\n            ``item_id`` columns.\n        item_id\n            Name of the column that, when grouped by, gives the different time\n            series.\n        **kwargs\n            Additional arguments. Same as of PandasDataset class.\n\n        Returns\n        -------\n        PandasDataset\n            Gluonts dataset based on ``pandas.DataFrame``s.\n        \"\"\"\n        return cls(dataframes=dict(list(dataframe.groupby(item_id))), **kwargs)\n\n\ndef series_to_dataframe(\n    series: Union[pd.Series, List[pd.Series], Dict[str, pd.Series]]\n) -> Union[pd.DataFrame, List[pd.DataFrame], Dict[str, pd.DataFrame]]:\n    def to_df(series):\n        assert isinstance(\n            series.index, DatetimeIndexOpsMixin\n        ), \"series index has to be a DatetimeIndex.\"\n        return series.to_frame(name=\"target\")\n\n    if isinstance(series, list):\n        return list(map(to_df, series))\n    elif isinstance(series, dict):\n        return valmap(to_df, series)\n    return to_df(series)\n\n\ndef is_series(series: Any) -> bool:\n    \"\"\"\n    return True if ``series`` is ``pd.Series`` or a collection of\n    ``pd.Series``.\n    \"\"\"\n    if isinstance(series, list):\n        return is_series(series[0])\n    elif isinstance(series, dict):\n        return is_series(list(series.values()))\n    return isinstance(series, pd.Series)\n\n\ndef as_dataentry(\n    data: pd.DataFrame,\n    target: Union[str, List[str]],\n    timestamp: Optional[str] = None,\n    feat_dynamic_real: List[str] = [],\n    feat_dynamic_cat: List[str] = [],\n    feat_static_real: List[str] = [],\n    feat_static_cat: List[str] = [],\n    past_feat_dynamic_real: List[str] = [],\n) -> DataEntry:\n    \"\"\"\n    Convert a single time series (uni- or multi-variate) that is given in\n    a pandas.DataFrame format to a DataEntry.\n\n    Parameters\n    ----------\n    data\n        pandas.DataFrame containing at least ``timestamp``, ``target`` and\n        ``item_id`` columns.\n    target\n        Name of the column that contains the ``target`` time series.\n        For multivariate targets ``target`` is expecting a list of column\n        names.\n    timestamp\n        Name of the column that contains the timestamp information.\n        If ``None`` the index of ``data`` is assumed to be the time.\n    feat_dynamic_real\n        List of column names that contain dynamic real features.\n    feat_dynamic_cat\n        List of column names that contain dynamic categorical features.\n    feat_static_real\n        List of column names that contain static real features.\n    feat_static_cat\n        List of column names that contain static categorical features.\n    past_feat_dynamic_real\n        List of column names that contain dynamic real features only for\n        the history.\n\n    Returns\n    -------\n    DataEntry\n        A dictionary with at least ``target`` and ``start`` field.\n    \"\"\"\n    start = data.loc[:, timestamp].iloc[0] if timestamp else data.index[0]\n    dataentry = {FieldName.START: start}\n\n    def set_field(fieldname, col_names, f=lambda x: x):\n        if col_names:\n            dataentry[fieldname] = [\n                f(data.loc[:, n].to_list()) for n in col_names\n            ]\n\n    if isinstance(target, str):\n        dataentry[FieldName.TARGET] = data.loc[:, target].to_list()\n    else:\n        set_field(FieldName.TARGET, target)\n    set_field(FieldName.FEAT_DYNAMIC_REAL, feat_dynamic_real)\n    set_field(FieldName.FEAT_DYNAMIC_CAT, feat_dynamic_cat)\n    set_field(FieldName.FEAT_STATIC_REAL, feat_static_real, lambda x: x[0])\n    set_field(FieldName.FEAT_STATIC_CAT, feat_static_cat, lambda x: x[0])\n    set_field(FieldName.PAST_FEAT_DYNAMIC_REAL, past_feat_dynamic_real)\n    return dataentry\n\n\ndef prepare_prediction_data(\n    dataentry: DataEntry, ignore_last_n_targets: int\n) -> DataEntry:\n    \"\"\"\n    Remove ``ignore_last_n_targets`` values from ``target`` and\n    ``past_feat_dynamic_real``.  Works in univariate and multivariate case.\n\n    >>> prepare_prediction_data(\n    >>>    {\"target\": np.array([1., 2., 3., 4.])}, ignore_last_n_targets=2\n    >>> )\n    {'target': array([1., 2.])}\n    \"\"\"\n    entry = deepcopy(dataentry)\n    for fname in [FieldName.TARGET, FieldName.PAST_FEAT_DYNAMIC_REAL]:\n        if fname in entry:\n            entry[fname] = entry[fname][..., :-ignore_last_n_targets]\n    return entry\n\n\ndef is_uniform(index: pd.PeriodIndex) -> bool:\n    \"\"\"\n    Check if ``index`` contains monotonically increasing periods, evenly spaced\n    with frequency ``index.freq``.\n\n    >>> ts = [\"2021-01-01 00:00\", \"2021-01-01 02:00\", \"2021-01-01 04:00\"]\n    >>> is_uniform(pd.DatetimeIndex(ts).to_period(\"2H\"))\n    True\n    >>> ts = [\"2021-01-01 00:00\", \"2021-01-01 04:00\"]\n    >>> is_uniform(pd.DatetimeIndex(ts).to_period(\"2H\"))\n    False\n    \"\"\"\n    return (index[1:] - index[:-1] == index.freq).all()\n", "path": "src/gluonts/dataset/pandas.py"}], "after_files": [{"content": "# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\").\n# You may not use this file except in compliance with the License.\n# A copy of the License is located at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# or in the \"license\" file accompanying this file. This file is distributed\n# on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n# express or implied. See the License for the specific language governing\n# permissions and limitations under the License.\n\nfrom copy import deepcopy\nfrom dataclasses import dataclass, field\nfrom typing import Any, cast, Dict, Iterator, List, Optional, Union\n\nimport pandas as pd\nfrom pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin\nfrom toolz import valmap\n\nfrom gluonts.dataset.common import DataEntry, ProcessDataEntry\nfrom gluonts.dataset.field_names import FieldName\n\n\n@dataclass\nclass PandasDataset:\n    \"\"\"\n    A pandas.DataFrame-based dataset type.\n\n    This class is constructed with a collection of pandas.DataFrame-objects\n    where each ``DataFrame`` is representing one time series.\n    A ``target`` and a ``timestamp`` columns are essential. Furthermore,\n    static/dynamic real/categorical features can be specified.\n\n    Parameters\n    ----------\n    dataframes\n        Single ``pd.DataFrame``/``pd.Series`` or a collection as list or dict\n        containing at least ``timestamp`` and ``target`` values.\n        If a Dict is provided, the key will be the associated ``item_id``.\n    target\n        Name of the column that contains the ``target`` time series.\n        For multivariate targets, a list of column names should be provided.\n    timestamp\n        Name of the column that contains the timestamp information.\n    freq\n        Frequency of observations in the time series. Must be a valid pandas\n        frequency.\n    feat_dynamic_real\n        List of column names that contain dynamic real features.\n    feat_dynamic_cat\n        List of column names that contain dynamic categorical features.\n    feat_static_real\n        List of column names that contain static real features.\n    feat_static_cat\n        List of column names that contain static categorical features.\n    past_feat_dynamic_real\n        List of column names that contain dynamic real features only for the\n        history.\n    ignore_last_n_targets\n        For target and past dynamic features last ``ignore_last_n_targets``\n        elements are removed when iterating over the data set. This becomes\n        important when the predictor is called.\n    \"\"\"\n\n    dataframes: Union[\n        pd.DataFrame,\n        pd.Series,\n        List[pd.DataFrame],\n        List[pd.Series],\n        Dict[str, pd.DataFrame],\n        Dict[str, pd.Series],\n    ]\n    target: Union[str, List[str]] = \"target\"\n    timestamp: Optional[str] = None\n    freq: Optional[str] = None\n    feat_dynamic_real: List[str] = field(default_factory=list)\n    feat_dynamic_cat: List[str] = field(default_factory=list)\n    feat_static_real: List[str] = field(default_factory=list)\n    feat_static_cat: List[str] = field(default_factory=list)\n    past_feat_dynamic_real: List[str] = field(default_factory=list)\n    ignore_last_n_targets: int = 0\n\n    def __post_init__(self) -> None:\n        if isinstance(self.target, list) and len(self.target) == 1:\n            self.target = self.target[0]\n        self.one_dim_target = not isinstance(self.target, list)\n\n        if is_series(self.dataframes):\n            self.dataframes = series_to_dataframe(self.dataframes)\n        # store data internally as List[Tuple[str, pandas.DataFrame]]\n        # if str is not empty it will be set in ``DataEntry`` as ``item_id``.\n        if isinstance(self.dataframes, dict):\n            self._dataframes = list(self.dataframes.items())\n        elif isinstance(self.dataframes, list):\n            self._dataframes = [(None, df) for df in self.dataframes]\n        else:  # case single dataframe\n            self._dataframes = [(None, self.dataframes)]\n\n        for i, (item_id, df) in enumerate(self._dataframes):\n            if self.timestamp:\n                df = df.set_index(keys=self.timestamp)\n\n            if not isinstance(df.index, pd.PeriodIndex):\n                df.index = pd.to_datetime(df.index)\n                df = df.to_period(freq=self.freq)\n\n            df.sort_index(inplace=True)\n\n            assert is_uniform(df.index), (\n                \"Dataframe index is not uniformly spaced. \"\n                \"If your dataframe contains data from multiple series in the \"\n                'same column (\"long\" format), consider constructing the '\n                \"dataset with `PandasDataset.from_long_dataframe` instead.\"\n            )\n\n            self._dataframes[i] = (item_id, df)\n\n        if not self.freq:  # infer frequency from index\n            self.freq = self._dataframes[0][1].index.freqstr\n\n        self.process = ProcessDataEntry(\n            cast(str, self.freq), one_dim_target=self.one_dim_target\n        )\n\n    def _dataentry(\n        self, item_id: Optional[str], df: pd.DataFrame\n    ) -> DataEntry:\n        dataentry = as_dataentry(\n            data=df,\n            target=self.target,\n            feat_dynamic_real=self.feat_dynamic_real,\n            feat_dynamic_cat=self.feat_dynamic_cat,\n            feat_static_real=self.feat_static_real,\n            feat_static_cat=self.feat_static_cat,\n            past_feat_dynamic_real=self.past_feat_dynamic_real,\n        )\n        if item_id is not None:\n            dataentry[\"item_id\"] = item_id\n        return dataentry\n\n    def __iter__(self) -> Iterator[DataEntry]:\n        for item_id, df in self._dataframes:\n            dataentry = self.process(self._dataentry(item_id, df))\n            if self.ignore_last_n_targets:\n                dataentry = prepare_prediction_data(\n                    dataentry, self.ignore_last_n_targets\n                )\n            yield dataentry\n\n    def __len__(self) -> int:\n        return len(self._dataframes)\n\n    @classmethod\n    def from_long_dataframe(\n        cls, dataframe: pd.DataFrame, item_id: str, **kwargs\n    ) -> \"PandasDataset\":\n        \"\"\"\n        Construct ``PandasDataset`` out of a long dataframe.\n        A long dataframe uses the long format for each variable. Target time\n        series values, for example, are stacked on top of each other rather\n        than side-by-side. The same is true for other dynamic or categorical\n        features.\n\n        Parameters\n        ----------\n        dataframe\n            pandas.DataFrame containing at least ``timestamp``, ``target`` and\n            ``item_id`` columns.\n        item_id\n            Name of the column that, when grouped by, gives the different time\n            series.\n        **kwargs\n            Additional arguments. Same as of PandasDataset class.\n\n        Returns\n        -------\n        PandasDataset\n            Gluonts dataset based on ``pandas.DataFrame``s.\n        \"\"\"\n        return cls(dataframes=dict(list(dataframe.groupby(item_id))), **kwargs)\n\n\ndef series_to_dataframe(\n    series: Union[pd.Series, List[pd.Series], Dict[str, pd.Series]]\n) -> Union[pd.DataFrame, List[pd.DataFrame], Dict[str, pd.DataFrame]]:\n    def to_df(series):\n        assert isinstance(\n            series.index, DatetimeIndexOpsMixin\n        ), \"series index has to be a DatetimeIndex.\"\n        return series.to_frame(name=\"target\")\n\n    if isinstance(series, list):\n        return list(map(to_df, series))\n    elif isinstance(series, dict):\n        return valmap(to_df, series)\n    return to_df(series)\n\n\ndef is_series(series: Any) -> bool:\n    \"\"\"\n    return True if ``series`` is ``pd.Series`` or a collection of\n    ``pd.Series``.\n    \"\"\"\n    if isinstance(series, list):\n        return is_series(series[0])\n    elif isinstance(series, dict):\n        return is_series(list(series.values()))\n    return isinstance(series, pd.Series)\n\n\ndef as_dataentry(\n    data: pd.DataFrame,\n    target: Union[str, List[str]],\n    timestamp: Optional[str] = None,\n    feat_dynamic_real: List[str] = [],\n    feat_dynamic_cat: List[str] = [],\n    feat_static_real: List[str] = [],\n    feat_static_cat: List[str] = [],\n    past_feat_dynamic_real: List[str] = [],\n) -> DataEntry:\n    \"\"\"\n    Convert a single time series (uni- or multi-variate) that is given in\n    a pandas.DataFrame format to a DataEntry.\n\n    Parameters\n    ----------\n    data\n        pandas.DataFrame containing at least ``timestamp``, ``target`` and\n        ``item_id`` columns.\n    target\n        Name of the column that contains the ``target`` time series.\n        For multivariate targets ``target`` is expecting a list of column\n        names.\n    timestamp\n        Name of the column that contains the timestamp information.\n        If ``None`` the index of ``data`` is assumed to be the time.\n    feat_dynamic_real\n        List of column names that contain dynamic real features.\n    feat_dynamic_cat\n        List of column names that contain dynamic categorical features.\n    feat_static_real\n        List of column names that contain static real features.\n    feat_static_cat\n        List of column names that contain static categorical features.\n    past_feat_dynamic_real\n        List of column names that contain dynamic real features only for\n        the history.\n\n    Returns\n    -------\n    DataEntry\n        A dictionary with at least ``target`` and ``start`` field.\n    \"\"\"\n    start = data.loc[:, timestamp].iloc[0] if timestamp else data.index[0]\n    dataentry = {FieldName.START: start}\n\n    def set_field(fieldname, col_names, f=lambda x: x):\n        if col_names:\n            dataentry[fieldname] = [\n                f(data.loc[:, n].to_list()) for n in col_names\n            ]\n\n    if isinstance(target, str):\n        dataentry[FieldName.TARGET] = data.loc[:, target].to_list()\n    else:\n        set_field(FieldName.TARGET, target)\n    set_field(FieldName.FEAT_DYNAMIC_REAL, feat_dynamic_real)\n    set_field(FieldName.FEAT_DYNAMIC_CAT, feat_dynamic_cat)\n    set_field(FieldName.FEAT_STATIC_REAL, feat_static_real, lambda x: x[0])\n    set_field(FieldName.FEAT_STATIC_CAT, feat_static_cat, lambda x: x[0])\n    set_field(FieldName.PAST_FEAT_DYNAMIC_REAL, past_feat_dynamic_real)\n    return dataentry\n\n\ndef prepare_prediction_data(\n    dataentry: DataEntry, ignore_last_n_targets: int\n) -> DataEntry:\n    \"\"\"\n    Remove ``ignore_last_n_targets`` values from ``target`` and\n    ``past_feat_dynamic_real``.  Works in univariate and multivariate case.\n\n    >>> prepare_prediction_data(\n    >>>    {\"target\": np.array([1., 2., 3., 4.])}, ignore_last_n_targets=2\n    >>> )\n    {'target': array([1., 2.])}\n    \"\"\"\n    entry = deepcopy(dataentry)\n    for fname in [FieldName.TARGET, FieldName.PAST_FEAT_DYNAMIC_REAL]:\n        if fname in entry:\n            entry[fname] = entry[fname][..., :-ignore_last_n_targets]\n    return entry\n\n\ndef is_uniform(index: pd.PeriodIndex) -> bool:\n    \"\"\"\n    Check if ``index`` contains monotonically increasing periods, evenly spaced\n    with frequency ``index.freq``.\n\n    >>> ts = [\"2021-01-01 00:00\", \"2021-01-01 02:00\", \"2021-01-01 04:00\"]\n    >>> is_uniform(pd.DatetimeIndex(ts).to_period(\"2H\"))\n    True\n    >>> ts = [\"2021-01-01 00:00\", \"2021-01-01 04:00\"]\n    >>> is_uniform(pd.DatetimeIndex(ts).to_period(\"2H\"))\n    False\n    \"\"\"\n    return (index[1:] - index[:-1] == index.freq).all()\n", "path": "src/gluonts/dataset/pandas.py"}]}