code: def filter_manifest_df(
      df,
      is_train_split=False,
      extra_filters=None,
      min_n_frames=5,
      max_n_frames=3000,
  ):
      filters = {
          "no speech": df["audio"] == "",
          f"short speech (<{min_n_frames} frames)": df["n_frames"]
          < min_n_frames,
          "empty sentence": df["tgt_text"] == "",
      }
      if is_train_split:
          filters[f"long speech (>{max_n_frames} frames)"] = (
              df["n_frames"] > max_n_frames
          )
      if extra_filters is not None:
          filters.update(extra_filters)
      invalid = reduce(lambda x, y: x | y, filters.values())
      valid = ~invalid
      print(
          "| "
          + ", ".join(f"{n}: {f.sum()}" for n, f in filters.items())
          + f", total {invalid.sum()} filtered, {valid.sum()} remained."
      )
      return df[valid]
  
imports: import csv
  from pathlib import Path
  import zipfile
  from functools import reduce
  from multiprocessing import cpu_count
  from typing import Any, Dict, List, Optional, Union
  import io
  import numpy
  import pandas
  import sentencepiece
  from fairseq.data.audio.audio_utils import convert_waveform, _get_kaldi_fbank, _get_torchaudio_fbank, is_npy_data, is_sf_audio_data
  import torch
  import soundfile
  from tqdm import tqdm
label_desc: Use image node_id 9 for calling a global function with example usage: filter_manifest_df(df, is_train_split, extra_filters, min_n_frames, max_n_frames) and returns: df