docs: def run_categorical_analysis(table, schema_list, args):
    """Find vocab values for the categorical columns and writes a csv file.
  
    The vocab files are in the from
    label1
    label2
    label3
    ...
  
    Args:
      table: Reference to FederatedTable (if bigquery_table is false) or a
          regular Table (otherwise)
      schema_list: Bigquery schema json object
      args: the command line args
    """
    import google.datalab.bigquery as bq
  
    # Get list of categorical columns.
    categorical_columns = []
    for col_schema in schema_list:
      col_type = col_schema['type'].lower()
      if col_type == 'string':
        categorical_columns.append(col_schema['name'])
  
    if categorical_columns:
      sys.stdout.write('Running categorical analysis...')
      for name in categorical_columns:
        if args.bigquery_table:
          table_name = parse_table_name(args.bigquery_table)
        else:
          table_name = 'table_name'
  
        sql = """
              SELECT
                {name}
              FROM
                {table}
              WHERE
                {name} IS NOT NULL
              GROUP BY
                {name}
              ORDER BY
                {name}
        """.format(name=name, table=table_name)
        out_file = os.path.join(args.output_dir,
                                CATEGORICAL_ANALYSIS_FILE % name)
  
        # extract_async seems to have a bug and sometimes hangs. So get the
        # results direclty.
        if args.bigquery_table:
          df = bq.Query(sql).execute().result().to_dataframe()
        else:
          query = bq.Query(sql, data_sources={'table_name': table})
          df = query.execute().result().to_dataframe()
  
        # Write the results to a file.
        string_buff = six.StringIO()
        df.to_csv(string_buff, index=False, header=False)
        file_io.write_string_to_file(out_file, string_buff.getvalue())
  
      sys.stdout.write('done.\n')