class_docstr: Time series encoder. This module can learn features for any `order_by` temporal column, both with and without accompanying target data.
  
  The backbone of this encoder is either a recurrent neural network or a transformer; both structured in an encoder-decoder fashion.
class_docstr_tok: ["Time","series","encoder",".","This","module","can","learn","features","for","any","`","order_by","`","temporal","column",",","both","with","and","without","accompanying","target","data",".","The","backbone","of","this","encoder","is","either","a","recurrent","neural","network","or","a","transformer",";","both","structured","in","an","encoder-decoder","fashion","."]
docstr: This method encodes one single row of serial data
  :param data: multidimensional time series as list of lists [[dim1_data], [dim2_data], ...]
               (dim_data: string with format "x11, x12, ... x1n")
  :param initial_hidden: if you want to encode from an initial hidden state other than 0s
  :param return_next_value:  if you want to return the next value in the time series too
  
  :return:  either encoded_value or (encoded_value, next_value)
docstr_tok: ["This","method","encodes","one","single","row","of","serial","data",":","param","data",":","multidimensional","time","series","as","list","of","lists","[","[","dim1_data","]",",","[","dim2_data","]",",","...","]","(","dim_data",":","string","with","format","``","x11",",","x12",",","...","x1n","''",")",":","param","initial_hidden",":","if","you","want","to","encode","from","an","initial","hidden","state","other","than","0s",":","param","return_next_value",":","if","you","want","to","return","the","next","value","in","the","time","series","too",":","return",":","either","encoded_value","or","(","encoded_value",",","next_value",")"]
code: def _encode_one(
      self,
      data,
      previous=None,
      initial_hidden=None,
      return_next_value=False,
  ):
      """
      This method encodes one single row of serial data
      :param data: multidimensional time series as list of lists [[dim1_data], [dim2_data], ...]
                   (dim_data: string with format "x11, x12, ... x1n")
      :param initial_hidden: if you want to encode from an initial hidden state other than 0s
      :param return_next_value:  if you want to return the next value in the time series too
  
      :return:  either encoded_value or (encoded_value, next_value)
      """
      self._encoder.eval()
      with torch.no_grad():
          # Convert to array and determine max length
          data, lengths_data = self._prepare_raw_data(data)
          self._max_ts_length = int(lengths_data.max())
  
          if self._normalizer:
              data = self._normalizer.encode(data).to(self.device)
              if len(data.shape) < 3:
                  data = data.unsqueeze(-1)
          else:
              data = (
                  torch.stack([d for d in data])
                  .unsqueeze(-1)
                  .to(self.device)
              )
  
          if previous is not None:
              target_tensor = torch.stack(previous).to(self.device)
              target_tensor[torch.isnan(target_tensor)] = 0.0
              if len(target_tensor.shape) < 3:
                  target_tensor = target_tensor.transpose(
                      0, 1
                  ).unsqueeze(0)
              data_tensor = torch.cat((data, target_tensor), dim=-1)
          else:
              data_tensor = data
  
          steps = data_tensor.shape[1]
  
          if self.encoder_class == EncoderRNNNumerical:
              encoder_hidden = self._encoder.init_hidden(self.device)
              encoder_hidden = (
                  encoder_hidden
                  if initial_hidden is None
                  else initial_hidden
              )
  
              next_tensor = None
              for tensor_i in range(steps):
                  next_tensor, encoder_hidden = self._encoder.forward(
                      data_tensor[:, tensor_i, :].unsqueeze(dim=0),
                      encoder_hidden,
                  )
  
          else:
              next_tensor = None
              len_batch = self._get_batch(lengths_data, 0, len(data))
              batch_size, timesteps, _ = data_tensor.shape
  
              for start_chunk in range(0, timesteps, timesteps):
                  data, targets, lengths_chunk = get_chunk(
                      data_tensor, len_batch, start_chunk, timesteps
                  )
                  data = data.transpose(0, 1)
                  next_tensor, encoder_hidden = self._encoder.forward(
                      data, lengths_chunk, self.device
                  )
  
      if return_next_value:
          return encoder_hidden, next_tensor
      else:
          return encoder_hidden
  
imports: import time
  from math import gcd
  from typing import List
  from copy import deepcopy
  import numpy
  import pandas
  import torch
  import torch.nn
  from torch import optim
  from type_infer.dtype import dtype
  from lightwood.helpers.log import log
  from lightwood.encoder.base import BaseEncoder
  from lightwood.helpers.device import get_device_from_name
  from lightwood.helpers.torch import LightwoodAutocast
  from lightwood.encoder.datetime import DatetimeNormalizerEncoder
  from lightwood.encoder.time_series.helpers.rnn_helpers import EncoderRNNNumerical, DecoderRNNNumerical
  from lightwood.encoder.helpers import MinMaxNormalizer, CatNormalizer
  from lightwood.encoder.time_series.helpers.transformer_helpers import TransformerEncoder, get_chunk, len_to_mask
label_desc: Use image node_id 7 for calling the TimeSeriesEncoder obj's underlying member method code with example usage: obj._encode_one(data, previous, initial_hidden, return_next_value) and returns: encoder_hidden,  next_tensor, encoder_hidden