class_docstr: Interface for simple dictionary-based dataset format using a
  compressed representation that uses the cartesian product between
  key dimensions. As with DictInterface, the dictionary keys correspond
  to the column (i.e. dimension) names and the values are NumPy arrays
  representing the values in that column.
  
  To use this compressed format, the key dimensions must be orthogonal
  to one another with each key dimension specifying an axis of the
  multidimensional space occupied by the value dimension data. For
  instance, given an temperature recordings sampled regularly across
  the earth surface, a list of N unique latitudes and M unique
  longitudes can specify the position of NxM temperature samples.
code: def init(cls, eltype, data, kdims, vdims):
      if kdims is None:
          kdims = eltype.kdims
      if vdims is None:
          vdims = eltype.vdims
  
      if not vdims:
          raise ValueError(
              "GridInterface interface requires at least "
              "one value dimension."
          )
  
      ndims = len(kdims)
      dimensions = [dimension_name(d) for d in kdims + vdims]
      vdim_tuple = tuple(dimension_name(vd) for vd in vdims)
  
      if isinstance(data, tuple):
          if (
              len(data) != len(dimensions)
              and len(data) == (ndims + 1)
              and len(data[-1].shape) == (ndims + 1)
          ):
              value_array = data[-1]
              data = {d: v for d, v in zip(dimensions, data[:-1])}
              data[vdim_tuple] = value_array
          else:
              data = {d: v for d, v in zip(dimensions, data)}
      elif isinstance(data, list) and data == []:
          if len(kdims) == 1:
              data = dict([(d, []) for d in dimensions])
          else:
              data = dict([(d.name, np.array([])) for d in kdims])
              if len(vdims) == 1:
                  data[vdims[0].name] = np.zeros((0, 0))
              else:
                  data[vdim_tuple] = np.zeros((0, 0, len(vdims)))
      elif not any(
          isinstance(
              data, tuple(t for t in interface.types if t is not None)
          )
          for interface in cls.interfaces.values()
      ):
          data = {k: v for k, v in zip(dimensions, zip(*data))}
      elif isinstance(data, np.ndarray):
          if data.shape == (0, 0) and len(vdims) == 1:
              array = data
              data = dict([(d.name, np.array([])) for d in kdims])
              data[vdims[0].name] = array
          elif data.shape == (0, 0, len(vdims)):
              array = data
              data = dict([(d.name, np.array([])) for d in kdims])
              data[vdim_tuple] = array
          else:
              if data.ndim == 1:
                  if (
                      eltype._auto_indexable_1d
                      and len(kdims) + len(vdims) > 1
                  ):
                      data = np.column_stack(
                          [np.arange(len(data)), data]
                      )
                  else:
                      data = np.atleast_2d(data).T
              data = {k: data[:, i] for i, k in enumerate(dimensions)}
      elif isinstance(data, list) and data == []:
          data = {d: np.array([]) for d in dimensions[:ndims]}
          data.update(
              {d: np.empty((0,) * ndims) for d in dimensions[ndims:]}
          )
      elif not isinstance(data, dict):
          raise TypeError(
              "GridInterface must be instantiated as a "
              "dictionary or tuple"
          )
  
      validate_dims = list(kdims)
      if vdim_tuple in data:
          if not isinstance(data[vdim_tuple], get_array_types()):
              data[vdim_tuple] = np.array(data[vdim_tuple])
      else:
          validate_dims += vdims
  
      for dim in validate_dims:
          name = dimension_name(dim)
          if name not in data:
              raise ValueError(f"Values for dimension {dim} not found")
          if not isinstance(data[name], get_array_types()):
              data[name] = np.array(data[name])
  
      kdim_names = [dimension_name(d) for d in kdims]
      if vdim_tuple in data:
          vdim_names = [vdim_tuple]
      else:
          vdim_names = [dimension_name(d) for d in vdims]
  
      expected = tuple([len(data[kd]) for kd in kdim_names])
      irregular_shape = data[kdim_names[0]].shape if kdim_names else ()
      valid_shape = (
          irregular_shape
          if len(irregular_shape) > 1
          else expected[::-1]
      )
      shapes = tuple([data[kd].shape for kd in kdim_names])
      for vdim in vdim_names:
          shape = data[vdim].shape
          error = DataError if len(shape) > 1 else ValueError
          if vdim_tuple in data:
              if shape[-1] != len(vdims):
                  raise error(
                      "The shape of the value array does not match the number of value dimensions."
                  )
              shape = shape[:-1]
          if (not expected and shape == (1,)) or (
              len(set((shape,) + shapes)) == 1 and len(shape) > 1
          ):
              # If empty or an irregular mesh
              pass
          elif len(shape) != len(expected):
              raise error(
                  "The shape of the %s value array does not "
                  "match the expected dimensionality indicated "
                  "by the key dimensions. Expected %d-D array, "
                  "found %d-D array."
                  % (vdim, len(expected), len(shape))
              )
          elif any(
              (e not in (s, s + 1)) for s, e in zip(shape, valid_shape)
          ):
              raise error(
                  f"Key dimension values and value array {vdim} "
                  f"shapes do not match. Expected shape {valid_shape}, "
                  f"actual shape: {shape}",
                  cls,
              )
      return data, {"kdims": kdims, "vdims": vdims}, {}
  
imports: from collections import defaultdict
  import numpy
  from ..None import util
  from ..dimension import dimension_name
  from ..element import Element
  from ..ndmapping import NdMapping, item_check, sorted_context
  from .dictionary import DictInterface
  from .interface import DataError, Interface
  from .util import dask_array_module, finite_range, get_array_types, is_dask
label_desc: Use image node_id 1 for calling the GridInterface obj's underlying member method code with example usage: obj.init(cls, eltype, data, kdims, vdims) and returns: data,  dict,  dict