docs: def find_discordant_snps(
          self, individual1, individual2, individual3=None, save_output=False
      ):
          """ Find discordant SNPs between two or three individuals.
  
          Parameters
          ----------
          individual1 : Individual
              reference individual (child if `individual2` and `individual3` are parents)
          individual2 : Individual
              comparison individual
          individual3 : Individual
              other parent if `individual1` is child and `individual2` is a parent
          save_output : bool
              specifies whether to save output to a CSV file in the output directory
  
          Returns
          -------
          pandas.DataFrame
              discordant SNPs and associated genetic data
  
          References
          ----------
          ..[1] David Pike, "Search for Discordant SNPs in Parent-Child
            Raw Data Files," David Pike's Utilities,
            http://www.math.mun.ca/~dapike/FF23utils/pair-discord.php
          ..[2] David Pike, "Search for Discordant SNPs when given data
            for child and both parents," David Pike's Utilities,
            http://www.math.mun.ca/~dapike/FF23utils/trio-discord.php
          """
          self._remap_snps_to_GRCh37([individual1, individual2, individual3])
  
          df = individual1.snps
  
          # remove nulls for reference individual
          df = df.loc[df["genotype"].notnull()]
  
          # add SNPs shared with `individual2`
          df = df.join(individual2.snps["genotype"], rsuffix="2")
  
          genotype1 = "genotype_" + individual1.get_var_name()
          genotype2 = "genotype_" + individual2.get_var_name()
  
          if individual3 is None:
              df = df.rename(columns={"genotype": genotype1, "genotype2": genotype2})
  
              # find discordant SNPs between reference and comparison individuals
              df = df.loc[
                  df[genotype2].notnull()
                  & (
                      (df[genotype1].str.len() == 1)
                      & (df[genotype2].str.len() == 1)
                      & (df[genotype1] != df[genotype2])
                  )
                  | (
                      (df[genotype1].str.len() == 2)
                      & (df[genotype2].str.len() == 2)
                      & (df[genotype1].str[0] != df[genotype2].str[0])
                      & (df[genotype1].str[0] != df[genotype2].str[1])
                      & (df[genotype1].str[1] != df[genotype2].str[0])
                      & (df[genotype1].str[1] != df[genotype2].str[1])
                  )
              ]
              if save_output:
                  save_df_as_csv(
                      df,
                      self._output_dir,
                      "discordant_snps_"
                      + individual1.get_var_name()
                      + "_"
                      + individual2.get_var_name()
                      + "_GRCh37.csv",
                  )
          else:
              # add SNPs shared with `individual3`
              df = df.join(individual3.snps["genotype"], rsuffix="3")
  
              genotype3 = "genotype_" + individual3.get_var_name()
  
              df = df.rename(
                  columns={
                      "genotype": genotype1,
                      "genotype2": genotype2,
                      "genotype3": genotype3,
                  }
              )
  
              # find discordant SNPs between child and two parents
              df = df.loc[
                  (
                      df[genotype2].notnull()
                      & (
                          (df[genotype1].str.len() == 1)
                          & (df[genotype2].str.len() == 1)
                          & (df[genotype1] != df[genotype2])
                      )
                      | (
                          (df[genotype1].str.len() == 2)
                          & (df[genotype2].str.len() == 2)
                          & (df[genotype1].str[0] != df[genotype2].str[0])
                          & (df[genotype1].str[0] != df[genotype2].str[1])
                          & (df[genotype1].str[1] != df[genotype2].str[0])
                          & (df[genotype1].str[1] != df[genotype2].str[1])
                      )
                  )
                  | (
                      df[genotype3].notnull()
                      & (
                          (df[genotype1].str.len() == 1)
                          & (df[genotype3].str.len() == 1)
                          & (df[genotype1] != df[genotype3])
                      )
                      | (
                          (df[genotype1].str.len() == 2)
                          & (df[genotype3].str.len() == 2)
                          & (df[genotype1].str[0] != df[genotype3].str[0])
                          & (df[genotype1].str[0] != df[genotype3].str[1])
                          & (df[genotype1].str[1] != df[genotype3].str[0])
                          & (df[genotype1].str[1] != df[genotype3].str[1])
                      )
                  )
                  | (
                      df[genotype2].notnull()
                      & df[genotype3].notnull()
                      & (df[genotype2].str.len() == 2)
                      & (df[genotype2].str[0] == df[genotype2].str[1])
                      & (df[genotype2] == df[genotype3])
                      & (df[genotype1] != df[genotype2])
                  )
              ]
  
              if save_output:
                  save_df_as_csv(
                      df,
                      self._output_dir,
                      "discordant_snps_"
                      + individual1.get_var_name()
                      + "_"
                      + individual2.get_var_name()
                      + "_"
                      + individual3.get_var_name()
                      + "_GRCh37.csv",
                  )
  
          return df