nodes: 0, module; 1, function_definition; 2, function_name:rank_targets; 3, parameters; 4, block; 5, identifier:sample_frame; 6, identifier:ref_targets; 7, identifier:ref_sample; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, while_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, expression_statement; 21, return_statement; 22, comment:"""Uses the geNorm algorithm to determine the most stably expressed
      genes from amongst ref_targets in your sample.
  
      See Vandesompele et al.'s 2002 Genome Biology paper for information about
      the algorithm: http://dx.doi.org/10.1186/gb-2002-3-7-research0034
  
      :param DataFrame sample_frame: A sample data frame.
      :param iterable ref_targets: A sequence of targets from the Target column
          of sample_frame to consider for ranking.
      :param string ref_sample: The name of a sample from the Sample
          column of sample_frame. It doesn't really matter what it is but it
          should exist for every target.
      :return: a sorted DataFrame with two columns, 'Target' and 'M' (the
          relative stability; lower means more stable).
      :rtype: DataFrame
      """; 23, assignment; 24, assignment; 25, assignment; 26, assignment; 27, assignment; 28, assignment; 29, assignment; 30, comparison_operator:len(ref_targets) - len(worst) > 1; 31, block; 32, assignment; 33, call; 34, call; 35, assignment; 36, call; 37, identifier:table; 38, call; 39, identifier:all_samples; 40, call; 41, identifier:t; 42, call; 43, identifier:logt; 44, call; 45, identifier:ref_targets; 46, call; 47, identifier:worst; 48, list; 49, identifier:worst_m; 50, list; 51, binary_operator:len(ref_targets) - len(worst); 52, integer:1; 53, expression_statement; 54, for_statement; 55, expression_statement; 56, expression_statement; 57, identifier:best; 58, binary_operator:ref_targets - set(worst); 59, attribute; 60, argument_list; 61, attribute; 62, argument_list; 63, identifier:worst_m; 64, binary_operator:[worst_m[0]] + worst_m; 65, attribute; 66, argument_list; 67, identifier:collect_expression; 68, argument_list; 69, attribute; 70, argument_list; 71, attribute; 72, argument_list; 73, identifier:log2; 74, argument_list; 75, identifier:set; 76, argument_list; 77, call; 78, call; 79, assignment; 80, identifier:test_target; 81, identifier:ref_targets; 82, block; 83, call; 84, call; 85, identifier:ref_targets; 86, call; 87, identifier:worst; 88, identifier:reverse; 89, identifier:worst_m; 90, identifier:reverse; 91, list; 92, identifier:worst_m; 93, identifier:pd; 94, identifier:DataFrame; 95, dictionary; 96, keyword_argument; 97, identifier:sample_frame; 98, identifier:ref_targets; 99, identifier:ref_sample; 100, subscript; 101, identifier:unique; 102, call; 103, identifier:mean; 104, identifier:t; 105, identifier:ref_targets; 106, identifier:len; 107, argument_list; 108, identifier:len; 109, argument_list; 110, identifier:M; 111, list; 112, if_statement; 113, expression_statement; 114, for_statement; 115, expression_statement; 116, attribute; 117, argument_list; 118, attribute; 119, argument_list; 120, identifier:set; 121, argument_list; 122, subscript; 123, pair; 124, pair; 125, identifier:columns; 126, list; 127, identifier:sample_frame; 128, string; 129, attribute; 130, argument_list; 131, identifier:ref_targets; 132, identifier:worst; 133, comparison_operator:test_target in worst; 134, block; 135, assignment; 136, identifier:ref_target; 137, identifier:ref_targets; 138, block; 139, call; 140, identifier:worst; 141, identifier:append; 142, subscript; 143, identifier:worst_m; 144, identifier:append; 145, subscript; 146, identifier:worst; 147, identifier:worst_m; 148, integer:0; 149, string; 150, binary_operator:list(best) + worst; 151, string; 152, identifier:worst_m; 153, string; 154, string; 155, string_content:Sample; 156, identifier:table; 157, identifier:groupby; 158, list; 159, identifier:test_target; 160, identifier:worst; 161, continue_statement; 162, identifier:Vs; 163, list; 164, if_statement; 165, expression_statement; 166, expression_statement; 167, attribute; 168, argument_list; 169, call; 170, integer:1; 171, call; 172, integer:0; 173, string_content:Target; 174, call; 175, identifier:worst; 176, string_content:M; 177, string_content:Target; 178, string_content:M; 179, string; 180, string; 181, boolean_operator; 182, block; 183, assignment; 184, call; 185, identifier:M; 186, identifier:append; 187, tuple; 188, identifier:max; 189, argument_list; 190, identifier:max; 191, argument_list; 192, identifier:list; 193, argument_list; 194, string_content:Sample; 195, string_content:Target; 196, comparison_operator:ref_target == test_target; 197, comparison_operator:ref_target in worst; 198, continue_statement; 199, identifier:A; 200, subscript; 201, attribute; 202, argument_list; 203, binary_operator:sum(Vs)/(len(ref_targets)-len(worst)-1); 204, identifier:test_target; 205, identifier:M; 206, identifier:M; 207, identifier:best; 208, identifier:ref_target; 209, identifier:test_target; 210, identifier:ref_target; 211, identifier:worst; 212, attribute; 213, call; 214, identifier:ref_target; 215, identifier:Vs; 216, identifier:append; 217, call; 218, call; 219, parenthesized_expression; 220, identifier:logt; 221, identifier:ix; 222, identifier:zip; 223, argument_list; 224, attribute; 225, argument_list; 226, identifier:sum; 227, argument_list; 228, binary_operator:len(ref_targets)-len(worst)-1; 229, identifier:all_samples; 230, call; 231, identifier:A; 232, identifier:std; 233, identifier:Vs; 234, binary_operator:len(ref_targets)-len(worst); 235, integer:1; 236, identifier:repeat; 237, argument_list; 238, call; 239, call; 240, identifier:test_target; 241, identifier:len; 242, argument_list; 243, identifier:len; 244, argument_list; 245, identifier:ref_targets; 246, identifier:worst
code: def rank_targets(sample_frame, ref_targets, ref_sample):
      """Uses the geNorm algorithm to determine the most stably expressed
      genes from amongst ref_targets in your sample.
  
      See Vandesompele et al.'s 2002 Genome Biology paper for information about
      the algorithm: http://dx.doi.org/10.1186/gb-2002-3-7-research0034
  
      :param DataFrame sample_frame: A sample data frame.
      :param iterable ref_targets: A sequence of targets from the Target column
          of sample_frame to consider for ranking.
      :param string ref_sample: The name of a sample from the Sample
          column of sample_frame. It doesn't really matter what it is but it
          should exist for every target.
      :return: a sorted DataFrame with two columns, 'Target' and 'M' (the
          relative stability; lower means more stable).
      :rtype: DataFrame
      """
      table = collect_expression(sample_frame, ref_targets, ref_sample)
      all_samples = sample_frame['Sample'].unique()
      t = table.groupby(['Sample', 'Target']).mean()
      logt = log2(t)
      ref_targets = set(ref_targets)
  
      worst = []
      worst_m = []
      while len(ref_targets) - len(worst) > 1:
          M = []
          for test_target in ref_targets:
              if test_target in worst: continue
              Vs = []
              for ref_target in ref_targets:
                  if ref_target == test_target or ref_target in worst: continue
                  A = logt.ix[zip(all_samples, repeat(test_target)), ref_target]
                  Vs.append(A.std())
              M.append( (sum(Vs)/(len(ref_targets)-len(worst)-1), test_target) )
          worst.append(max(M)[1])
          worst_m.append(max(M)[0])
      best = ref_targets - set(worst)
      worst.reverse()
      worst_m.reverse()
      worst_m = [worst_m[0]] + worst_m
      return pd.DataFrame({'Target': list(best) + worst, 'M': worst_m}, columns=['Target', 'M'])