code: def shuffled_batches(self, batch_size):
          
          if batch_size >= self.size:
              yield self
          else:
              batch_splits = math_util.divide_ceiling(self.size, batch_size)
              indices = list(range(self.size))
              np.random.shuffle(indices)
  
              for sub_indices in np.array_split(indices, batch_splits):
                  yield Transitions(
                      size=len(sub_indices),
                      environment_information=None,
                      # Dont use it in batches for a moment, can be uncommented later if needed
                      # environment_information=[info[sub_indices.tolist()] for info in self.environment_information]
                      transition_tensors={k: v[sub_indices] for k, v in self.transition_tensors.items()}
                      # extra_data does not go into batches
                  )
docs: Generate randomized batches of data