nodes: 0, module; 1, function_definition; 2, function_name:from_product; 3, parameters; 4, block; 5, identifier:cls; 6, identifier:iterables; 7, default_parameter; 8, default_parameter; 9, expression_statement; 10, import_from_statement; 11, import_from_statement; 12, if_statement; 13, expression_statement; 14, expression_statement; 15, return_statement; 16, identifier:sortorder; 17, None; 18, identifier:names; 19, None; 20, comment:"""
          Make a MultiIndex from the cartesian product of multiple iterables.
  
          Parameters
          ----------
          iterables : list / sequence of iterables
              Each iterable has unique labels for each level of the index.
          sortorder : int or None
              Level of sortedness (must be lexicographically sorted by that
              level).
          names : list / sequence of str, optional
              Names for the levels in the index.
  
          Returns
          -------
          index : MultiIndex
  
          See Also
          --------
          MultiIndex.from_arrays : Convert list of arrays to MultiIndex.
          MultiIndex.from_tuples : Convert list of tuples to MultiIndex.
          MultiIndex.from_frame : Make a MultiIndex from a DataFrame.
  
          Examples
          --------
          >>> numbers = [0, 1, 2]
          >>> colors = ['green', 'purple']
          >>> pd.MultiIndex.from_product([numbers, colors],
          ...                            names=['number', 'color'])
          MultiIndex(levels=[[0, 1, 2], ['green', 'purple']],
                     codes=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]],
                     names=['number', 'color'])
          """; 21, dotted_name; 22, dotted_name; 23, dotted_name; 24, dotted_name; 25, not_operator; 26, block; 27, elif_clause; 28, assignment; 29, assignment; 30, call; 31, identifier:pandas; 32, identifier:core; 33, identifier:arrays; 34, identifier:categorical; 35, identifier:_factorize_from_iterables; 36, identifier:pandas; 37, identifier:core; 38, identifier:reshape; 39, identifier:util; 40, identifier:cartesian_product; 41, call; 42, raise_statement; 43, call; 44, block; 45, pattern_list; 46, call; 47, identifier:codes; 48, call; 49, identifier:MultiIndex; 50, argument_list; 51, identifier:is_list_like; 52, argument_list; 53, call; 54, identifier:is_iterator; 55, argument_list; 56, expression_statement; 57, identifier:codes; 58, identifier:levels; 59, identifier:_factorize_from_iterables; 60, argument_list; 61, identifier:cartesian_product; 62, argument_list; 63, identifier:levels; 64, identifier:codes; 65, keyword_argument; 66, keyword_argument; 67, identifier:iterables; 68, identifier:TypeError; 69, argument_list; 70, identifier:iterables; 71, assignment; 72, identifier:iterables; 73, identifier:codes; 74, identifier:sortorder; 75, identifier:sortorder; 76, identifier:names; 77, identifier:names; 78, string:"Input must be a list / sequence of iterables."; 79, identifier:iterables; 80, call; 81, identifier:list; 82, argument_list; 83, identifier:iterables
code: def from_product(cls, iterables, sortorder=None, names=None):
          """
          Make a MultiIndex from the cartesian product of multiple iterables.
  
          Parameters
          ----------
          iterables : list / sequence of iterables
              Each iterable has unique labels for each level of the index.
          sortorder : int or None
              Level of sortedness (must be lexicographically sorted by that
              level).
          names : list / sequence of str, optional
              Names for the levels in the index.
  
          Returns
          -------
          index : MultiIndex
  
          See Also
          --------
          MultiIndex.from_arrays : Convert list of arrays to MultiIndex.
          MultiIndex.from_tuples : Convert list of tuples to MultiIndex.
          MultiIndex.from_frame : Make a MultiIndex from a DataFrame.
  
          Examples
          --------
          >>> numbers = [0, 1, 2]
          >>> colors = ['green', 'purple']
          >>> pd.MultiIndex.from_product([numbers, colors],
          ...                            names=['number', 'color'])
          MultiIndex(levels=[[0, 1, 2], ['green', 'purple']],
                     codes=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]],
                     names=['number', 'color'])
          """
          from pandas.core.arrays.categorical import _factorize_from_iterables
          from pandas.core.reshape.util import cartesian_product
  
          if not is_list_like(iterables):
              raise TypeError("Input must be a list / sequence of iterables.")
          elif is_iterator(iterables):
              iterables = list(iterables)
  
          codes, levels = _factorize_from_iterables(iterables)
          codes = cartesian_product(codes)
          return MultiIndex(levels, codes, sortorder=sortorder, names=names)