Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'pandas._libs.tslibs.offsets.YearBegin' object has no attribute '_period_dtype_code' #3153

Open
baharian opened this issue Mar 27, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@baharian
Copy link

Description

Training a CanonicalRNNEstimator model leads to the following error:
AttributeError: 'pandas._libs.tslibs.offsets.YearBegin' object has no attribute '_period_dtype_code'

Weirdly enough, using the same dataset to train a MQRNNEstimator model (with its extra estimator parameters) works fine. I have made sure that the pandas DataFrame is not irregular and that all time-steps for all item_ids do have non-NULL values. The only difference (apart from the parameters specific to each estimator) is that my version of MQRNNEstimator sets the seeds, whereas I am using the vanilla CanonicalRNNEstimator in GluonTS.

To Reproduce

train_ds = PandasDataset\
                    .from_long_dataframe(
                        dataframe = train_df,
                        target = 'q',
                        item_id = 'item_id',
                        timestamp = 'timestamp',
                        freq = 'Y',
                        static_feature_columns = ['group'])

history = TrainingHistory()
estimator_params = {
    'freq': 'Y',
    'prediction_length': 1,
    'context_length': 4,
    'trainer': Trainer(epochs = 50, learning_rate = 1e-4, callbacks = [history]),
}

estimator = CanonicalRNNEstimator(**estimator_params)
predictor = estimator.train(train_ds)

Error message or code output

  0%|                                                                                                                | 0/50 [00:00<?, ?it/s]

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File <timed exec>:16

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/mx/model/estimator.py:239, in GluonEstimator.train(self, training_data, validation_data, shuffle_buffer_length, cache_data, **kwargs)
    231 def train(
    232     self,
    233     training_data: Dataset,
   (...)
    237     **kwargs,
    238 ) -> Predictor:
--> 239     return self.train_model(
    240         training_data=training_data,
    241         validation_data=validation_data,
    242         shuffle_buffer_length=shuffle_buffer_length,
    243         cache_data=cache_data,
    244     ).predictor

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/mx/model/estimator.py:216, in GluonEstimator.train_model(self, training_data, validation_data, from_predictor, shuffle_buffer_length, cache_data)
    213 else:
    214     copy_parameters(from_predictor.network, training_network)
--> 216 self.trainer(
    217     net=training_network,
    218     train_iter=training_data_loader,
    219     validation_iter=validation_data_loader,
    220 )
    222 with self.trainer.ctx:
    223     predictor = self.create_predictor(transformation, training_network)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/mx/trainer/_base.py:420, in Trainer.__call__(self, net, train_iter, validation_iter)
    415 curr_lr = trainer.learning_rate
    416 logger.info(
    417     f"Epoch[{epoch_no}] Learning rate is {curr_lr}"
    418 )
--> 420 epoch_loss = loop(
    421     epoch_no,
    422     train_iter,
    423     num_batches_to_use=self.num_batches_per_epoch,
    424 )
    426 should_continue = self.callbacks.on_train_epoch_end(
    427     epoch_no=epoch_no,
    428     epoch_loss=loss_value(epoch_loss),
    429     training_network=net,
    430     trainer=trainer,
    431 )
    433 if is_validation_available:

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/mx/trainer/_base.py:275, in Trainer.__call__.<locals>.loop(epoch_no, batch_iter, num_batches_to_use, is_training)
    272 it = tqdm(batch_iter, total=num_batches_to_use)
    273 any_batches = False
--> 275 for batch_no, batch in enumerate(it, start=1):
    276     any_batches = True
    278     # `batch` here is expected to be a dictionary whose fields
    279     # should correspond 1-to-1 with the network inputs
    280     # see below how `batch.values()` is fed into the network

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/tqdm/std.py:1182, in tqdm.__iter__(self)
   1179 time = self._time
   1181 try:
-> 1182     for obj in iterable:
   1183         yield obj
   1184         # Update and possibly print the progressbar.
   1185         # Note: does not call self.update(1) for speed optimisation.

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/itertools.py:415, in IterableSlice.__iter__(self)
    414 def __iter__(self):
--> 415     yield from itertools.islice(self.iterable, self.length)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:111, in TransformedDataset.__iter__(self)
    110 def __iter__(self) -> Iterator[DataEntry]:
--> 111     yield from self.transformation(
    112         self.base_dataset, is_train=self.is_train
    113     )

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:132, in MapTransformation.__call__(self, data_it, is_train)
    129 def __call__(
    130     self, data_it: Iterable[DataEntry], is_train: bool
    131 ) -> Iterator:
--> 132     for data_entry in data_it:
    133         try:
    134             yield self.map_transform(data_entry.copy(), is_train)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/dataset/loader.py:50, in Batch.__call__(self, data, is_train)
     49 def __call__(self, data, is_train):
---> 50     yield from batcher(data, self.batch_size)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/itertools.py:131, in batcher.<locals>.get_batch()
    130 def get_batch():
--> 131     return list(itertools.islice(it, batch_size))

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:132, in MapTransformation.__call__(self, data_it, is_train)
    129 def __call__(
    130     self, data_it: Iterable[DataEntry], is_train: bool
    131 ) -> Iterator:
--> 132     for data_entry in data_it:
    133         try:
    134             yield self.map_transform(data_entry.copy(), is_train)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:186, in FlatMapTransformation.__call__(self, data_it, is_train)
    182 def __call__(
    183     self, data_it: Iterable[DataEntry], is_train: bool
    184 ) -> Iterator:
    185     num_idle_transforms = 0
--> 186     for data_entry in data_it:
    187         num_idle_transforms += 1
    188         for result in self.flatmap_transform(data_entry.copy(), is_train):

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/itertools.py:87, in Cyclic.__iter__(self)
     85 at_least_one = False
     86 while True:
---> 87     for el in self.iterable:
     88         at_least_one = True
     89         yield el

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:111, in TransformedDataset.__iter__(self)
    110 def __iter__(self) -> Iterator[DataEntry]:
--> 111     yield from self.transformation(
    112         self.base_dataset, is_train=self.is_train
    113     )

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:132, in MapTransformation.__call__(self, data_it, is_train)
    129 def __call__(
    130     self, data_it: Iterable[DataEntry], is_train: bool
    131 ) -> Iterator:
--> 132     for data_entry in data_it:
    133         try:
    134             yield self.map_transform(data_entry.copy(), is_train)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:132, in MapTransformation.__call__(self, data_it, is_train)
    129 def __call__(
    130     self, data_it: Iterable[DataEntry], is_train: bool
    131 ) -> Iterator:
--> 132     for data_entry in data_it:
    133         try:
    134             yield self.map_transform(data_entry.copy(), is_train)

    [... skipping similar frames: MapTransformation.__call__ at line 132 (1 times)]

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/transform/_base.py:132, in MapTransformation.__call__(self, data_it, is_train)
    129 def __call__(
    130     self, data_it: Iterable[DataEntry], is_train: bool
    131 ) -> Iterator:
--> 132     for data_entry in data_it:
    133         try:
    134             yield self.map_transform(data_entry.copy(), is_train)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/dataset/pandas.py:217, in PandasDataset.__iter__(self)
    216 def __iter__(self):
--> 217     yield from self._data_entries
    218     self.unchecked = True

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/gluonts/dataset/pandas.py:174, in PandasDataset._pair_to_dataentry(self, item_id, df)
    169     df.index = pd.DatetimeIndex(df[self.timestamp]).to_period(
    170         freq=self.freq
    171     )
    173 if not isinstance(df.index, pd.PeriodIndex):
--> 174     df = df.to_period(freq=self.freq)
    176 if not self.assume_sorted:
    177     df.sort_index(inplace=True)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/pandas/core/frame.py:11985, in DataFrame.to_period(self, freq, axis, copy)
  11982 if not isinstance(old_ax, DatetimeIndex):
  11983     raise TypeError(f"unsupported Type {type(old_ax).__name__}")
> 11985 new_ax = old_ax.to_period(freq=freq)
  11987 setattr(new_obj, axis_name, new_ax)
  11988 return new_obj

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/pandas/core/indexes/extension.py:95, in _inherit_from_data.<locals>.method(self, *args, **kwargs)
     93 if "inplace" in kwargs:
     94     raise ValueError(f"cannot use inplace with {type(self).__name__}")
---> 95 result = attr(self._data, *args, **kwargs)
     96 if wrap:
     97     if isinstance(result, type(self._data)):

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/pandas/core/arrays/datetimes.py:1224, in DatetimeArray.to_period(self, freq)
   1220         res = freq
   1222     freq = res
-> 1224 return PeriodArray._from_datetime64(self._ndarray, freq, tz=self.tz)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/pandas/core/arrays/period.py:322, in PeriodArray._from_datetime64(cls, data, freq, tz)
    307 @classmethod
    308 def _from_datetime64(cls, data, freq, tz=None) -> Self:
    309     """
    310     Construct a PeriodArray from a datetime64 array
    311 
   (...)
    320     PeriodArray[freq]
    321     """
--> 322     data, freq = dt64arr_to_periodarr(data, freq, tz)
    323     dtype = PeriodDtype(freq)
    324     return cls(data, dtype=dtype)

File ~/miniconda3/envs/gluonts_env/lib/python3.11/site-packages/pandas/core/arrays/period.py:1167, in dt64arr_to_periodarr(data, freq, tz)
   1165 reso = get_unit_from_dtype(data.dtype)
   1166 freq = Period._maybe_convert_freq(freq)
-> 1167 base = freq._period_dtype_code
   1168 return c_dt64arr_to_periodarr(data.view("i8"), base, tz, reso=reso), freq

AttributeError: 'pandas._libs.tslibs.offsets.YearBegin' object has no attribute '_period_dtype_code'

Environment

  • Operating system: Linux
  • Python version: 3.11.5
  • pandas version: 2.1.2
  • MXNet version: 1.9.1
  • GluonTS version: 0.14.0
@baharian baharian added the bug Something isn't working label Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant