Identifies repeated experimental values and returns mean values for those
    data along with their standard deviation. Only aggregates experimental
    values that have been acquired at the same temperature and pressure.

    Parameters
    ----------
    model_name: dev_model
        the dev_model object to be interrogated
    keep_descriptors: boolean, default False
        if True descriptors will be included in the output DataFrame

    Returns
    -----------
    out: dataframe
        pandas DataFrame of the original data where repeated measurements
        have been averaged and their variance stored in a separate column

def merge_duplicates(model_name, keep_descriptors=False):
    """
    Identifies repeated experimental values and returns mean values for those
    data along with their standard deviation. Only aggregates experimental
    values that have been acquired at the same temperature and pressure.

    Parameters
    ----------
    model_name: dev_model
        the dev_model object to be interrogated
    keep_descriptors: boolean, default False
        if True descriptors will be included in the output DataFrame

    Returns
    -----------
    out: dataframe
        pandas DataFrame of the original data where repeated measurements
        have been averaged and their variance stored in a separate column
    """
    model_outputs = -6 + model_name.Data_summary.shape[0]
    devmodel = model_name
    cols = devmodel.Data.columns
    if (devmodel.Data.iloc[:, -(4 + model_outputs):-4].max() < 700).all():
        for output_index in range(model_outputs):
            devmodel.Data.iloc[:, -(5 + output_index)] = \
                devmodel.Data.iloc[:, -(5 + output_index)].apply(
                lambda x: exp(float(x)))
    output_val = pd.DataFrame()
    output_xtd = pd.DataFrame()
    for output_index in range(model_outputs):
        val = devmodel.Data.groupby(['smiles-cation', 'smiles-anion']
                                    )[cols[-(5 + output_index)]].mean().\
            reset_index()
        xtd = devmodel.Data.groupby(['smiles-cation', 'smiles-anion']
                                    )[cols[-(5 + output_index)]].std().\
            reset_index()
        if output_index == 0:
            output_val = val
            output_xtd = xtd
        else:
            output_val = pd.merge(output_val, val)
            output_xtd = pd.merge(output_xtd, xtd)
    size = devmodel.Data.groupby(['smiles-cation', 'smiles-anion']
                                 )[cols[-(5 + output_index)]].count().\
        reset_index()
    cations = devmodel.Data.groupby(['smiles-cation', 'smiles-anion']
                                    )['name-cation'].first().reset_index()
    anions = devmodel.Data.groupby(['smiles-cation', 'smiles-anion']
                                   )['name-anion'].first().reset_index()

    size.columns.values[2] = "count"

    salts = (devmodel.Data["smiles-cation"] + "." + devmodel.
             Data["smiles-anion"]).unique()
    print("Identified {} unique salts in {} datapoints".
          format(len(salts), devmodel.Data.shape[0]))
    out = pd.merge(output_val, output_xtd,
                   on=['smiles-cation', 'smiles-anion'],
                   suffixes=['_mean', '_std'])
    out = pd.merge(out, size)
    out = pd.merge(out, cations)
    out = pd.merge(out, anions)
    if keep_descriptors:
        cationDescriptors = load_data("cationDescriptors.csv")
        cationDescriptors.columns = [str(col) + '-cation' for
                                     col in cationDescriptors.columns]
        anionDescriptors = load_data("anionDescriptors.csv")
        anionDescriptors.columns = [str(col) + '-anion' for
                                    col in anionDescriptors.columns]
        new_df = pd.merge(cationDescriptors, out,
                          on=["name-cation", "smiles-cation"], how="right")
        new_df = pd.merge(anionDescriptors, new_df,
                          on=["name-anion", "smiles-anion"], how="right")
        out = new_df
    return out