class_docstr: A replay buffer that stores episodes of transitions. The additional structure allows performing various
  calculations of total return and other values that depend on the sequential behavior of the transitions
  in the episode.
class_docstr_tok: ["A","replay","buffer","that","stores","episodes","of","transitions",".","The","additional","structure","allows","performing","various","calculations","of","total","return","and","other","values","that","depend","on","the","sequential","behavior","of","the","transitions","in","the","episode","."]
docstr: Get an generator for iterating through the shuffled replay buffer, for processing the data in epochs.
  If the requested size is larger than the number of samples available in the replay buffer then the batch will
  return empty. The last returned batch may be smaller than the size requested, to accommodate for all the
  transitions in the replay buffer.
  
  :param size: the size of the batch to return
  :return: a batch (list) of selected transitions from the replay buffer
code: def get_shuffled_training_data_generator(
      self, size: int
  ) -> List[Transition]:
      """
      Get an generator for iterating through the shuffled replay buffer, for processing the data in epochs.
      If the requested size is larger than the number of samples available in the replay buffer then the batch will
      return empty. The last returned batch may be smaller than the size requested, to accommodate for all the
      transitions in the replay buffer.
  
      :param size: the size of the batch to return
      :return: a batch (list) of selected transitions from the replay buffer
      """
      self.reader_writer_lock.lock_writing()
  
      shuffled_transition_indices = list(
          range(self.last_training_set_transition_id)
      )
      random.shuffle(shuffled_transition_indices)
  
      # The last batch drawn will usually be < batch_size (=the size variable)
      for i in range(
          math.ceil(len(shuffled_transition_indices) / size)
      ):
          sample_data = [
              self.transitions[j]
              for j in shuffled_transition_indices[
                  i * size : (i + 1) * size
              ]
          ]
          self.reader_writer_lock.release_writing()
  
          yield sample_data
  
imports: import ast
  import pickle
  from copy import deepcopy
  import math
  import pandas
  from typing import List, Tuple, Union
  import numpy
  import random
  from rl_coach.core_types import Transition, Episode
  from rl_coach.filters.filter import InputFilter
  from rl_coach.logger import screen
  from rl_coach.memories.memory import Memory, MemoryGranularity, MemoryParameters
  from rl_coach.utils import ReaderWriterLock, ProgressBar
  from rl_coach.core_types import CsvDataset
label_desc: Use image node_id 10 for calling the EpisodicExperienceReplay obj's underlying member method code with example usage: obj.get_shuffled_training_data_generator(size) without return types