Calculates expression of samples in a sample data frame relative to a
    single reference gene and reference sample using the ∆∆Cq method.

    For best results, the ref_sample should be defined for all targets and the
    ref_target should be defined for all samples, or else the series you get
    back will have lots of NaNs.
    
    :param DataFrame sample_frame: A sample data frame.
    :param string ref_target: A string matching an entry of the Target column;
        the target to use as the reference target (e.g. 'Gapdh')
    :param string ref_sample: A string matching an entry of the Sample column.
    :return: a Series of expression values for each row of the sample data
        frame.
    :rtype: Series

def expression_ddcq(sample_frame, ref_target, ref_sample):
    """Calculates expression of samples in a sample data frame relative to a
    single reference gene and reference sample using the ∆∆Cq method.

    For best results, the ref_sample should be defined for all targets and the
    ref_target should be defined for all samples, or else the series you get
    back will have lots of NaNs.
    
    :param DataFrame sample_frame: A sample data frame.
    :param string ref_target: A string matching an entry of the Target column;
        the target to use as the reference target (e.g. 'Gapdh')
    :param string ref_sample: A string matching an entry of the Sample column.
    :return: a Series of expression values for each row of the sample data
        frame.
    :rtype: Series
    """
    # It might be more correct to replace asarray calls (to discard indexes)
    # with proper joins.
  
    ref_target_df = sample_frame.ix[sample_frame['Target'] == ref_target, ['Sample', 'Cq']]
    ref_target_grouped = ref_target_df.groupby('Sample')
    ref_target_mean_by_sample = ref_target_grouped['Cq'].aggregate(average_cq)
    ref_target_mean_list = ref_target_mean_by_sample.ix[sample_frame['Sample']]
    ref_target_delta = asarray(ref_target_mean_list - ref_target_mean_by_sample[ref_sample])

    ref_sample_df = sample_frame.ix[sample_frame['Sample'] == ref_sample, ['Target', 'Cq']]
    ref_sample_grouped = ref_sample_df.groupby('Target')
    ref_sample_mean_by_target = ref_sample_grouped['Cq'].aggregate(average_cq)
    ref_sample_delta = asarray(sample_frame['Cq'] - asarray(ref_sample_mean_by_target.ix[sample_frame['Target']]))

    rel_exp = pd.Series(
            power(2, ref_target_delta - ref_sample_delta),
            index = sample_frame.index)

    return rel_exp