class_docstr: Abstract data generator.
class_docstr_tok: ["Abstract","data","generator","."]
code: def _4d_scipy_matrix_to_values(
      feature_array: FeatureArray,
  ) -> List[np.ndarray]:
      # in case of dialogue data we may have 4 dimensions
      # batch size x dialogue history length x sequence length x number of features
  
      # transformers cannot handle 4D tensors, therefore pad and reshape the data
      # so that the resulting tensor is 3D
      # the shape is (sum of dialogue history length for all tensors in the
      # batch x max sequence length x number of features)
      # the original shape and the original dialogue length is passed on to the model
      # it can be used to transform the 3D tensor back into 4D
  
      # in order to create 4d tensor inputs, we created "fake" zero features
      # for nonexistent inputs. To save calculation we filter this features before
      # input to tf methods.
      number_of_features = feature_array[0][0].shape[-1]
      array_of_array_of_sparse = (
          RasaDataGenerator._filter_out_fake_inputs(feature_array)
      )
      if not array_of_array_of_sparse:
          # create empty array with appropriate last dims
          return [
              np.empty((0, 3), dtype=np.int64),
              np.array([], dtype=np.float32),
              np.array([0, 0, number_of_features], dtype=np.int64),
          ]
  
      # we need to make sure that the matrices are coo_matrices otherwise the
      # transformation does not work (e.g. you cannot access x.row, x.col)
      if not isinstance(
          array_of_array_of_sparse[0][0], scipy.sparse.coo_matrix
      ):
          array_of_array_of_sparse = [
              [
                  x.tocoo()
                  if isinstance(x, scipy.sparse.spmatrix)
                  else x
                  for x in array_of_sparse
              ]
              for array_of_sparse in array_of_array_of_sparse
          ]
  
      dialogue_len = [
          len(array_of_sparse)
          for array_of_sparse in array_of_array_of_sparse
      ]
      combined_dialogue_len = sum(dialogue_len)
      max_seq_len = max(
          [
              x.shape[0]
              for array_of_sparse in array_of_array_of_sparse
              for x in array_of_sparse
          ]
      )
      # get the indices of values
      indices = np.hstack(
          [
              np.vstack(
                  [
                      sum(dialogue_len[:i]) + j * np.ones_like(x.row),
                      x.row,
                      x.col,
                  ]
              )
              for i, array_of_sparse in enumerate(
                  array_of_array_of_sparse
              )
              for j, x in enumerate(array_of_sparse)
          ]
      ).T
  
      data = np.hstack(
          [
              x.data
              for array_of_sparse in array_of_array_of_sparse
              for x in array_of_sparse
          ]
      )
  
      shape = np.array(
          (combined_dialogue_len, max_seq_len, number_of_features)
      )
  
      return [
          indices.astype(np.int64),
          data.astype(np.float32),
          shape.astype(np.int64),
      ]
  
imports: import math
  from typing import List, Union, Text, Optional, Any, Tuple, Dict, cast
  import logging
  import scipy.sparse
  import numpy
  from tensorflow.keras.utils import Sequence
  from rasa.utils.tensorflow.constants import SEQUENCE, BALANCED
  from rasa.utils.tensorflow.model_data import RasaModelData, Data, FeatureArray
label_desc: Use image node_id 10 for calling the RasaDataGenerator obj's underlying member method code with example usage: obj._4d_scipy_matrix_to_values(feature_array) and returns: list, list