code: import pandas as pd
  
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  def df_summary (df):
      info = df.info()
      describe = df.describe()
      nulls = df.isnull().sum()/len(df)*100
      value_count = df.value_counts()
      return info, describe, nulls, value_count
  
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  def missing_zero_values_table(df):
      '''This function will look at any data set and report back on zeros and nulls for every column while also giving percentages of total values
          and also the data types. The message prints out the shape of the data frame and also tells you how many columns have nulls '''
      zero_val = (df == 0.00).astype(int).sum(axis=0)
      null_count = df.isnull().sum()
      mis_val_percent = 100 * df.isnull().sum() / len(df)
      mz_table = pd.concat([zero_val, null_count, mis_val_percent], axis=1)
      mz_table = mz_table.rename(
      columns = {0 : 'Zero Values', 1 : 'null_count', 2 : '% of Total Values'})
      mz_table['Total Zeroes + Null Values'] = mz_table['Zero Values'] + mz_table['null_count']
      mz_table['% Total Zero + Null Values'] = 100 * mz_table['Total Zeroes + Null Values'] / len(df)
      mz_table['Data Type'] = df.dtypes
      mz_table = mz_table[
          mz_table.iloc[:,1] >= 0].sort_values(
          '% of Total Values', ascending=False).round(1)
      print ("Your selected dataframe has " + str(df.shape[1]) + " columns and " + str(df.shape[0]) + " Rows.\n"      
              "There are " +  str((mz_table['null_count'] != 0).sum()) +
            " columns that have NULL values.")
      return mz_table, missing_zero_values_table(df)
apis: pandas.concat