class_docstr: Generates a gridded Dataset of 2D aggregate arrays indexed by the
  first two dimensions of the passed Element, turning all remaining
  dimensions into value dimensions. The key dimensions of the
  gridded array are treated as categorical indices. Useful for data
  indexed by two independent categorical variables such as a table
  of population values indexed by country and year. Data that is
  indexed by continuous dimensions should be binned before
  aggregation. The aggregation will retain the global sorting order
  of both dimensions.
  
  >> table = Table([('USA', 2000, 282.2), ('UK', 2005, 58.89)],
                   kdims=['Country', 'Year'], vdims=['Population'])
  >> categorical_aggregate2d(table)
  Dataset({'Country': ['USA', 'UK'], 'Year': [2000, 2005],
           'Population': [[ 282.2 , np.nan], [np.nan,   58.89]]},
          kdims=['Country', 'Year'], vdims=['Population'])
class_docstr_tok: ["Generates","a","gridded","Dataset","of","2D","aggregate","arrays","indexed","by","the","first","two","dimensions","of","the","passed","Element",",","turning","all","remaining","dimensions","into","value","dimensions",".","The","key","dimensions","of","the","gridded","array","are","treated","as","categorical","indices",".","Useful","for","data","indexed","by","two","independent","categorical","variables","such","as","a","table","of","population","values","indexed","by","country","and","year",".","Data","that","is","indexed","by","continuous","dimensions","should","be","binned","before","aggregation",".","The","aggregation","will","retain","the","global","sorting","order","of","both","dimensions",".",">",">","table","=","Table","(","[","(","'USA","'",",","2000",",","282.2",")",",","(","'UK","'",",","2005",",","58.89",")","]",",","kdims=","[","'Country","'",",","'Year","'","]",",","vdims=","[","'Population","'","]",")",">",">","categorical_aggregate2d","(","table",")","Dataset","(","{","'Country","'",":","[","'USA","'",",","'UK","'","]",",","'Year","'",":","[","2000",",","2005","]",",","'Population","'",":","[","[","282.2",",","np.nan","]",",","[","np.nan",",","58.89","]","]","}",",","kdims=","[","'Country","'",",","'Year","'","]",",","vdims=","[","'Population","'","]",")"]
docstr: Get the coordinates of the 2D aggregate, maintaining the correct
  sorting order.
docstr_tok: ["Get","the","coordinates","of","the","2D","aggregate",",","maintaining","the","correct","sorting","order","."]
code: def _get_coords(cls, obj):
      """
      Get the coordinates of the 2D aggregate, maintaining the correct
      sorting order.
      """
      xdim, ydim = obj.dimensions(label=True)[:2]
      xcoords = obj.dimension_values(xdim, False)
      ycoords = obj.dimension_values(ydim, False)
      if xcoords.dtype.kind not in "SUO":
          xcoords = np.sort(xcoords)
      if ycoords.dtype.kind not in "SUO":
          return xcoords, np.sort(ycoords)
  
      # Determine global orderings of y-values using topological sort
      grouped = obj.groupby(
          xdim, container_type=dict, group_type=Dataset
      ).values()
      orderings = {}
      sort = True
      for group in grouped:
          vals = group.dimension_values(ydim, False)
          if len(vals) == 1:
              orderings[vals[0]] = [vals[0]]
          else:
              for i in range(len(vals) - 1):
                  p1, p2 = vals[i : i + 2]
                  orderings[p1] = [p2]
          if sort:
              if vals.dtype.kind in ("i", "f"):
                  sort = (np.diff(vals) >= 0).all()
              else:
                  sort = np.array_equal(np.sort(vals), vals)
      if sort or one_to_one(orderings, ycoords):
          ycoords = np.sort(ycoords)
      elif not is_cyclic(orderings):
          coords = list(itertools.chain(*sort_topologically(orderings)))
          ycoords = (
              coords
              if len(coords) == len(ycoords)
              else np.sort(ycoords)
          )
      return np.asarray(xcoords), np.asarray(ycoords)
  
imports: import itertools
  import numpy
  import pandas
  import param
  from ..core import Dataset
  from ..core.boundingregion import BoundingBox
  from ..core.data import PandasInterface, default_datatype
  from ..core.operation import Operation
  from ..core.sheetcoords import Slice
  from ..core.util import cartesian_product, datetime_types, is_cyclic, is_nan, one_to_one, sort_topologically
label_desc: Use image node_id 1 for calling the categorical_aggregate2d obj's underlying member method code with example usage: obj._get_coords(cls, obj) and returns: np,  np, xcoords,  np