code: def write_bottom_half(f, row_metadata_df, data_df, data_null, data_float_format, metadata_null):
      
      # create the left side of the bottom half of the gct (for the row metadata)
      size_of_left_bottom_half_df = (row_metadata_df.shape[0],
                                1 + row_metadata_df.shape[1])
      left_bottom_half_df = pd.DataFrame(np.full(size_of_left_bottom_half_df, metadata_null, dtype=object))
  
      #create the full bottom half by combining with the above with the matrix data
      bottom_half_df = pd.concat([left_bottom_half_df, data_df.reset_index(drop=True)], axis=1)
      bottom_half_df.columns = range(bottom_half_df.shape[1])
  
      # Insert the rids
      bottom_half_df.iloc[:, 0] = row_metadata_df.index.values
  
      # Insert the row metadata, but first convert to strings and replace NaNs
      row_metadata_col_indices = range(1, 1 + row_metadata_df.shape[1])
      bottom_half_df.iloc[:, row_metadata_col_indices] = (
          row_metadata_df.astype(str).replace("nan", value=metadata_null).values)
  
      # Write bottom_half_df to file
      bottom_half_df.to_csv(f, header=False, index=False, sep="\t",
                            na_rep=data_null,
                            float_format=data_float_format)
docs: Write the bottom half of the gct file: row metadata and data.
  
      Args:
          f (file handle): handle for output file
          row_metadata_df (pandas df)
          data_df (pandas df)
          data_null (string): how to represent missing values in the data
          metadata_null (string): how to represent missing values in the metadata
          data_float_format (string): how many decimal points to keep in representing data
  
      Returns:
          None