code: def Data(
      name: str,
      value,
      *,
      dims: Optional[Sequence[str]] = None,
      coords: Optional[Dict[str, Union[Sequence, np.ndarray]]] = None,
      export_index_as_coords=False,
      infer_dims_and_coords=False,
      mutable: Optional[bool] = None,
      **kwargs,
  ) -> Union[SharedVariable, TensorConstant]:
      """Data container that registers a data variable with the model.
  
      Depending on the ``mutable`` setting (default: True), the variable
      is registered as a :class:`~pytensor.compile.sharedvalue.SharedVariable`,
      enabling it to be altered in value and shape, but NOT in dimensionality using
      :func:`pymc.set_data`.
  
      To set the value of the data container variable, check out
      :meth:`pymc.Model.set_data`.
  
      When making predictions or doing posterior predictive sampling, the shape of the
      registered data variable will most likely need to be changed.  If you encounter an
      PyTensor shape mismatch error, refer to the documentation for
      :meth:`pymc.model.set_data`.
  
      For more information, read the notebook :ref:`nb:data_container`.
  
      Parameters
      ----------
      name : str
          The name for this variable.
      value : array_like or pandas.Series, pandas.Dataframe
          A value to associate with this variable.
      dims : str or tuple of str, optional
          Dimension names of the random variables (as opposed to the shapes of these
          random variables). Use this when ``value`` is a pandas Series or DataFrame. The
          ``dims`` will then be the name of the Series / DataFrame's columns. See ArviZ
          documentation for more information about dimensions and coordinates:
          :ref:`arviz:quickstart`.
          If this parameter is not specified, the random variables will not have dimension
          names.
      coords : dict, optional
          Coordinate values to set for new dimensions introduced by this ``Data`` variable.
      export_index_as_coords : bool
          Deprecated, previous version of "infer_dims_and_coords"
      infer_dims_and_coords : bool, default=False
          If True, the ``Data`` container will try to infer what the coordinates
          and dimension names should be if there is an index in ``value``.
      mutable : bool, optional
          Switches between creating a :class:`~pytensor.compile.sharedvalue.SharedVariable`
          (``mutable=True``) vs. creating a :class:`~pytensor.tensor.TensorConstant`
          (``mutable=False``).
          Consider using :class:`pymc.ConstantData` or :class:`pymc.MutableData` as less
          verbose alternatives to ``pm.Data(..., mutable=...)``.
          If this parameter is not specified, the value it takes will depend on the
          version of the package. Since ``v4.1.0`` the default value is
          ``mutable=False``, with previous versions having ``mutable=True``.
      **kwargs : dict, optional
          Extra arguments passed to :func:`pytensor.shared`.
  
      Examples
      --------
      >>> import pymc as pm
      >>> import numpy as np
      >>> # We generate 10 datasets
      >>> true_mu = [np.random.randn() for _ in range(10)]
      >>> observed_data = [mu + np.random.randn(20) for mu in true_mu]
  
      >>> with pm.Model() as model:
      ...     data = pm.MutableData('data', observed_data[0])
      ...     mu = pm.Normal('mu', 0, 10)
      ...     pm.Normal('y', mu=mu, sigma=1, observed=data)
  
      >>> # Generate one trace for each dataset
      >>> idatas = []
      >>> for data_vals in observed_data:
      ...     with model:
      ...         # Switch out the observed dataset
      ...         model.set_data('data', data_vals)
      ...         idatas.append(pm.sample())
      """
      if coords is None:
          coords = {}
  
      if isinstance(value, list):
          value = np.array(value)
  
      # Add data container to the named variables of the model.
      model = pm.Model.get_context(error_if_none=False)
      if model is None:
          raise TypeError(
              "No model on context stack, which is needed to instantiate a data container. "
              "Add variable inside a 'with model:' block."
          )
      name = model.name_for(name)
  
      # `convert_observed_data` takes care of parameter `value` and
      # transforms it to something digestible for PyTensor.
      arr = convert_observed_data(value)
      if isinstance(arr, np.ma.MaskedArray):
          raise NotImplementedError(
              "Masked arrays or arrays with `nan` entries are not supported. "
              "Pass them directly to `observed` if you want to trigger auto-imputation"
          )
  
      if mutable is None:
          warnings.warn(
              "The `mutable` kwarg was not specified. Before v4.1.0 it defaulted to `pm.Data(mutable=True)`,"
              " which is equivalent to using `pm.MutableData()`."
              " In v4.1.0 the default changed to `pm.Data(mutable=False)`, equivalent to `pm.ConstantData`."
              " Use `pm.ConstantData`/`pm.MutableData` or pass `pm.Data(..., mutable=False/True)` to avoid this warning.",
              UserWarning,
          )
          mutable = False
      if mutable:
          x = pytensor.shared(arr, name, **kwargs)
      else:
          x = pt.as_tensor_variable(arr, name, **kwargs)
  
      if isinstance(dims, str):
          dims = (dims,)
      if not (dims is None or len(dims) == x.ndim):
          raise pm.exceptions.ShapeError(
              "Length of `dims` must match the dimensions of the dataset.",
              actual=len(dims),
              expected=x.ndim,
          )
  
      # Optionally infer coords and dims from the input value.
      if export_index_as_coords:
          infer_dims_and_coords = export_index_as_coords
          warnings.warn(
              "Deprecation warning: 'export_index_as_coords; is deprecated and will be removed in future versions. Please use 'infer_dims_and_coords' instead.",
              DeprecationWarning,
          )
  
      if infer_dims_and_coords:
          coords, dims = determine_coords(model, value, dims)
  
      if dims:
          if not mutable:
              # Use the dimension lengths from the before it was tensorified.
              # These can still be tensors, but in many cases they are numeric.
              xshape = np.shape(arr)
          else:
              xshape = x.shape
          # Register new dimension lengths
          for d, dname in enumerate(dims):
              if dname not in model.dim_lengths:
                  model.add_coord(
                      name=dname,
                      # Note: Coordinate values can't be taken from
                      # the value, because it could be N-dimensional.
                      values=coords.get(dname, None),
                      mutable=mutable,
                      length=xshape[d],
                  )
  
      model.add_named_variable(x, dims=dims)
  
      return x
  
imports: import io
  import urllib.request
  import warnings
  from copy import copy
  from typing import Dict, Optional, Sequence, Tuple, Union, cast
  import numpy
  import pandas
  import pytensor
  import pytensor.tensor
  import xarray
  from pytensor.compile.sharedvalue import SharedVariable
  from pytensor.raise_op import Assert
  from pytensor.scalar import Cast
  from pytensor.tensor.elemwise import Elemwise
  from pytensor.tensor.random.basic import IntegersRV
  from pytensor.tensor.subtensor import AdvancedSubtensor
  from pytensor.tensor.type import TensorType
  from pytensor.tensor.variable import TensorConstant, TensorVariable
  import pymc
  from pymc.pytensorf import convert_observed_data
label_desc: Use image node_id 9 for calling a global function with example usage: Data(name, value) and returns: x