code: def _to_dataframes(
      metrics_or_plots: Iterable[Union[MetricsForSlice, PlotsForSlice]],
      column_prefixes: _ColumnPrefixes,
      include_empty_columns: bool = False,
  ) -> Dict[str, pd.DataFrame]:
      """The implementation of loading TFMA metrics or plots as DataFrames.
  
      Args:
        metrics_or_plots: an iterable of MetricsForSlice or PlotsForSlice.
        column_prefixes: the column names of the first layer columns of the
          multi-index columns.
        include_empty_columns: if True, keeps all the unset fields with value set to
          None.
  
      Returns:
        A map of the DataFrame type to the corresponding DataFrame.
      """
      slice_key_name = column_prefixes.slices
      metric_key_name = column_prefixes.metric_keys
      metric_value_name = column_prefixes.metric_values
      column_data = collections.defaultdict(_ColumnData)
      index = 0
      # For each slice.
      for metrics_or_plots_for_slice in metrics_or_plots:
          slices = [
              (
                  single_slice_key.column,
                  _get_slice_value(single_slice_key),
              )
              for single_slice_key in metrics_or_plots_for_slice.slice_key.single_slice_keys
          ]
          # For each metric inside the slice.
          if isinstance(metrics_or_plots_for_slice, MetricsForSlice):
              key_and_values = (
                  metrics_or_plots_for_slice.metric_keys_and_values
              )
          elif isinstance(metrics_or_plots_for_slice, PlotsForSlice):
              key_and_values = (
                  metrics_or_plots_for_slice.plot_keys_and_values
              )
          else:
              raise NotImplementedError(
                  f"{type(metrics_or_plots_for_slice)} is not supported."
              )
          for key_and_value in key_and_values:
              metric_value = key_and_value.value
              for field in metric_value.DESCRIPTOR.fields:
                  metric_type = field.name
                  metric = getattr(metric_value, metric_type)
                  if (
                      isinstance(metric, message.Message)
                      and not metric_value.HasField(metric_type)
                      or not metric
                  ):
                      continue
                  # Flattens the metric_values.
                  # Initializes index_end to 'index - 1' to indicate that there is no item
                  # added yet. It is set to 'index' once the loop starts, indicating that
                  # at least one item is found.
                  index_end = index - 1
                  for k, v, index_end in _flatten_proto(
                      metric_value, metric_type, index
                  ):
                      column_data[metric_type].values[k].append(
                          (v, index_end)
                      )
                  # index_end is later used as the exclusive range end, thus, the +1.
                  index_end += 1
                  # Insert a column per leaf field in MetricKey.
                  for k, v, _ in _flatten_proto(
                      key_and_value,
                      "key",
                      index,
                      include_empty_columns=include_empty_columns,
                  ):
                      column_data[metric_type].metric_keys[k].extend(
                          [(v, i) for i in range(index, index_end)]
                      )
                  # Insert each slice
                  if slices:
                      for slice_name, slice_value in slices:
                          column_data[metric_type].slices[
                              slice_name
                          ].extend(
                              [slice_value, i]
                              for i in range(index, index_end)
                          )
                  else:
                      column_data[metric_type].slices[_OVERALL].extend(
                          ["", i] for i in range(index, index_end)
                      )
                  index = index_end
      dfs = {}
      for metric_type, data in column_data.items():
          columns = pd.MultiIndex.from_tuples(
              [(slice_key_name, key) for key in data.slices]
              + [(metric_key_name, key) for key in data.metric_keys]
              + [(metric_value_name, key) for key in data.values]
          )
          all_data = itertools.chain(
              data.slices.values(),
              data.metric_keys.values(),
              data.values.values(),
          )
          df = pd.DataFrame(
              {
                  column: pd.Series(*zip(*values))
                  for column, values in zip(columns, all_data)
              }
          )
          dfs[metric_type] = df
      return dfs
  
imports: import collections
  import dataclasses
  import itertools
  from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple, Union
  import numpy
  import pandas
  from tensorflow_model_analysis.proto import metrics_for_slice_pb2
  from google.protobuf import wrappers_pb2
  from google.protobuf import descriptor
  from google.protobuf import message
label_desc: Use image node_id 3 for calling a global function with example usage: _to_dataframes(metrics_or_plots, column_prefixes, include_empty_columns) and returns: dfs