code: def convert_to_dataset_feature_statistics(
      df: pd.DataFrame,
  ) -> facet_feature_statistics_pb2.DatasetFeatureStatistics:
      """
      Converts the data statistics from DataFrame format to DatasetFeatureStatistics proto.
  
      :param df: The DataFrame for which feature statistics need to be computed.
      :return: A DatasetFeatureStatistics proto.
      """
      fs_proto = facet_feature_statistics_pb2.FeatureNameStatistics
      feature_stats = (
          facet_feature_statistics_pb2.DatasetFeatureStatistics()
      )
      data_type_custom_stat = (
          facet_feature_statistics_pb2.CustomStatistic()
      )
      kwargs = (
          {}
          if Version(pd.__version__) >= Version("2.0.0rc0")
          else {"datetime_is_numeric": True}
      )
      pandas_describe = df.describe(include="all", **kwargs)
      feature_stats.num_examples = len(df)
      quantiles_to_get = [x * 10 / 100 for x in range(10 + 1)]
      try:
          quantiles = df.select_dtypes(include="number").quantile(
              quantiles_to_get
          )
      except Exception:
          raise MlflowException("Error in generating quantiles")
  
      for key in df:
          pandas_describe_key = pandas_describe[key]
          current_column_value = df[key]
          data_type = current_column_value.dtype
          data_type_custom_stat.name = "data type"
          data_type_custom_stat.str = str(data_type)
          feat = feature_stats.features.add(
              type=get_facet_type_from_numpy_type(data_type),
              name=key.encode("utf-8"),
              custom_stats=[data_type_custom_stat],
          )
          if feat.type in (fs_proto.INT, fs_proto.FLOAT):
              feat_stats = feat.num_stats
  
              converter = datetime_and_timedelta_converter(
                  current_column_value.dtype
              )
              if converter:
                  date_time_converted = converter(current_column_value)
                  current_column_value = pd.DataFrame(
                      date_time_converted
                  )[0]
                  kwargs = (
                      {}
                      if Version(pd.__version__) >= Version("2.0.0rc0")
                      else {"datetime_is_numeric": True}
                  )
                  pandas_describe_key = current_column_value.describe(
                      include="all", **kwargs
                  )
                  quantiles[key] = current_column_value.quantile(
                      quantiles_to_get
                  )
  
              default_value = 0
              feat_stats.std_dev = pandas_describe_key.get(
                  "std", default_value
              )
              feat_stats.mean = pandas_describe_key.get(
                  "mean", default_value
              )
              feat_stats.min = pandas_describe_key.get(
                  "min", default_value
              )
              feat_stats.max = pandas_describe_key.get(
                  "max", default_value
              )
              feat_stats.median = current_column_value.median()
              feat_stats.num_zeros = (current_column_value == 0).sum()
              feat_stats.common_stats.CopyFrom(
                  compute_common_stats(current_column_value)
              )
  
              if key in quantiles:
                  equal_width_hist = histogram_generator.generate_equal_width_histogram(
                      quantiles=quantiles[key].to_numpy(),
                      num_buckets=10,
                      total_freq=feat_stats.common_stats.num_non_missing,
                  )
                  if equal_width_hist:
                      feat_stats.histograms.append(equal_width_hist)
                  equal_height_hist = histogram_generator.generate_equal_height_histogram(
                      quantiles=quantiles[key].to_numpy(),
                      num_buckets=10,
                  )
                  if equal_height_hist:
                      feat_stats.histograms.append(equal_height_hist)
          elif feat.type == fs_proto.STRING:
              is_current_column_boolean_type = False
              if current_column_value.dtype == bool:
                  current_column_value = current_column_value.replace(
                      {True: "True", False: "False"}
                  )
                  is_current_column_boolean_type = True
              feat_stats = feat.string_stats
              strs = current_column_value.dropna()
  
              feat_stats.avg_length = (
                  np.mean(np.vectorize(len)(strs))
                  if not is_current_column_boolean_type
                  and not current_column_value.isnull().all()
                  else 0
              )
              vals, counts = np.unique(strs, return_counts=True)
              feat_stats.unique = pandas_describe_key.get(
                  "unique", len(vals)
              )
              sorted_vals = sorted(zip(counts, vals), reverse=True)
              sorted_vals = sorted_vals[
                  :HISTOGRAM_CATEGORICAL_LEVELS_COUNT
              ]
              for val_index, val in enumerate(sorted_vals):
                  try:
                      if sys.version_info.major < 3 or isinstance(
                          val[1], (bytes, bytearray)
                      ):
                          printable_val = val[1].decode(
                              "UTF-8", "strict"
                          )
                      else:
                          printable_val = val[1]
                  except (UnicodeDecodeError, UnicodeEncodeError):
                      printable_val = "__BYTES_VALUE__"
                  bucket = feat_stats.rank_histogram.buckets.add(
                      low_rank=val_index,
                      high_rank=val_index,
                      sample_count=val[0].item(),
                      label=printable_val,
                  )
                  if val_index < 2:
                      feat_stats.top_values.add(
                          value=bucket.label,
                          frequency=bucket.sample_count,
                      )
  
              feat_stats.common_stats.CopyFrom(
                  compute_common_stats(current_column_value)
              )
  
      return feature_stats
  
file_path: mlflow/mlflow/recipes/cards/pandas_renderer.py
imports: import base64
  import sys
  from typing import Iterable, Tuple, Union
  import numpy
  import pandas
  from packaging.version import Version
  from mlflow.exceptions import MlflowException
  from mlflow.protos import facet_feature_statistics_pb2
  from mlflow.recipes.cards import histogram_generator
label_desc: Use image node_id 4 for calling a global function with example usage: convert_to_dataset_feature_statistics(df) and returns: feature_stats