nodes: 0, module; 1, function_definition; 2, function_name:flatten; 3, parameters; 4, block; 5, identifier:weights; 6, expression_statement; 7, comment:# NOQA; 8, if_statement; 9, return_statement; 10, comment:"""
      Flatten weights into a long DataFrame.
  
      Parameters
      ----------
      weights: pandas.DataFrame or dict
          A DataFrame of instrument weights with a MultiIndex where the top level
          contains pandas. Timestamps and the second level is instrument names.
          The columns consist of generic names. If dict is given this should be
          a dict of pandas.DataFrame in the above format, with keys for different
          root generics, e.g. 'CL'
  
      Returns
      -------
      A long DataFrame of weights, where columns are "date", "contract",
      "generic" and "weight". If a dictionary is passed, DataFrame will contain
      additional colum "key" containing the key value and be sorted according to
      this key value.
  
      Example
      -------
      >>> import pandas as pd
      >>> import mapping.util as util
      >>> vals = [[1, 0], [0, 1], [1, 0], [0, 1]]
      >>> widx = pd.MultiIndex.from_tuples([(pd.Timestamp('2015-01-03'), 'CLF5'),
      ...                                   (pd.Timestamp('2015-01-03'), 'CLG5'),
      ...                                   (pd.Timestamp('2015-01-04'), 'CLG5'),
      ...                                   (pd.Timestamp('2015-01-04'), 'CLH5')])
      >>> weights = pd.DataFrame(vals, index=widx, columns=["CL1", "CL2"])
      >>> util.flatten(weights)
      """; 11, call; 12, block; 13, elif_clause; 14, else_clause; 15, identifier:wts; 16, identifier:isinstance; 17, argument_list; 18, expression_statement; 19, expression_statement; 20, call; 21, block; 22, block; 23, identifier:weights; 24, attribute; 25, assignment; 26, assignment; 27, identifier:isinstance; 28, argument_list; 29, expression_statement; 30, for_statement; 31, expression_statement; 32, raise_statement; 33, identifier:pd; 34, identifier:DataFrame; 35, identifier:wts; 36, call; 37, attribute; 38, list; 39, identifier:weights; 40, identifier:dict; 41, assignment; 42, identifier:key; 43, call; 44, block; 45, assignment; 46, call; 47, attribute; 48, argument_list; 49, identifier:wts; 50, identifier:columns; 51, string:"date"; 52, string:"contract"; 53, string:"generic"; 54, string:"weight"; 55, identifier:wts; 56, list; 57, identifier:sorted; 58, argument_list; 59, expression_statement; 60, expression_statement; 61, expression_statement; 62, expression_statement; 63, identifier:wts; 64, call; 65, identifier:ValueError; 66, argument_list; 67, call; 68, identifier:reset_index; 69, call; 70, assignment; 71, assignment; 72, assignment; 73, call; 74, attribute; 75, argument_list; 76, string:"weights must be pd.DataFrame or dict"; 77, attribute; 78, argument_list; 79, attribute; 80, argument_list; 81, identifier:wt; 82, call; 83, attribute; 84, list; 85, subscript; 86, identifier:key; 87, attribute; 88, argument_list; 89, call; 90, identifier:reset_index; 91, keyword_argument; 92, identifier:weights; 93, identifier:stack; 94, identifier:weights; 95, identifier:keys; 96, attribute; 97, argument_list; 98, identifier:wt; 99, identifier:columns; 100, string:"date"; 101, string:"contract"; 102, string:"generic"; 103, string:"weight"; 104, attribute; 105, slice; 106, string:"key"; 107, identifier:wts; 108, identifier:append; 109, identifier:wt; 110, attribute; 111, argument_list; 112, identifier:drop; 113, True; 114, call; 115, identifier:reset_index; 116, identifier:wt; 117, identifier:loc; 118, identifier:pd; 119, identifier:concat; 120, identifier:wts; 121, keyword_argument; 122, attribute; 123, argument_list; 124, identifier:axis; 125, integer:0; 126, subscript; 127, identifier:stack; 128, identifier:weights; 129, identifier:key
code: def flatten(weights):
      """
      Flatten weights into a long DataFrame.
  
      Parameters
      ----------
      weights: pandas.DataFrame or dict
          A DataFrame of instrument weights with a MultiIndex where the top level
          contains pandas. Timestamps and the second level is instrument names.
          The columns consist of generic names. If dict is given this should be
          a dict of pandas.DataFrame in the above format, with keys for different
          root generics, e.g. 'CL'
  
      Returns
      -------
      A long DataFrame of weights, where columns are "date", "contract",
      "generic" and "weight". If a dictionary is passed, DataFrame will contain
      additional colum "key" containing the key value and be sorted according to
      this key value.
  
      Example
      -------
      >>> import pandas as pd
      >>> import mapping.util as util
      >>> vals = [[1, 0], [0, 1], [1, 0], [0, 1]]
      >>> widx = pd.MultiIndex.from_tuples([(pd.Timestamp('2015-01-03'), 'CLF5'),
      ...                                   (pd.Timestamp('2015-01-03'), 'CLG5'),
      ...                                   (pd.Timestamp('2015-01-04'), 'CLG5'),
      ...                                   (pd.Timestamp('2015-01-04'), 'CLH5')])
      >>> weights = pd.DataFrame(vals, index=widx, columns=["CL1", "CL2"])
      >>> util.flatten(weights)
      """  # NOQA
      if isinstance(weights, pd.DataFrame):
          wts = weights.stack().reset_index()
          wts.columns = ["date", "contract", "generic", "weight"]
      elif isinstance(weights, dict):
          wts = []
          for key in sorted(weights.keys()):
              wt = weights[key].stack().reset_index()
              wt.columns = ["date", "contract", "generic", "weight"]
              wt.loc[:, "key"] = key
              wts.append(wt)
          wts = pd.concat(wts, axis=0).reset_index(drop=True)
      else:
          raise ValueError("weights must be pd.DataFrame or dict")
  
      return wts