code: def compute_expected_is_or_wis_estimator(
      df: pd.DataFrame,
      policy: "Policy",
      num_actions: int,
      is_wis: bool = False,
  ) -> Tuple[float, float]:
      """Computes the expected IS or WIS estimator for the given policy and data.
  
      The policy is assumed to be deterministic over some discrete action space. i.e. the
      output of a policy has probablity 1.0 over the action it chooses.
  
      Args:
          df: The data to compute the estimator for.
          policy: The policy to compute the estimator for.
          num_actions: The number of actions in the action space.
          is_wis: Whether to compute the IS or WIS estimator.
  
      Returns:
          A tuple of the estimator value and the standard error of the estimator.
      """
      sample_batch = {
          SampleBatch.OBS: np.vstack(df[SampleBatch.OBS].values)
      }
  
      actions, _, extra_outs = policy.compute_actions_from_input_dict(
          sample_batch, explore=False
      )
  
      logged_actions = df[SampleBatch.ACTIONS].astype(int)
      ips_gain = (
          num_actions
          * sum(
              df[SampleBatch.REWARDS]
              * (1.0 * (actions == logged_actions).values)
          )
          / df[SampleBatch.REWARDS].sum()
      )
      avg_ips_weight = (
          num_actions
          * sum((1.0 * (actions == logged_actions).values))
          / len(actions)
      )
  
      if is_wis:
          gain = float(ips_gain / avg_ips_weight)
      else:
          gain = float(ips_gain)
  
      ips_gain_vec = (
          num_actions
          * df[SampleBatch.REWARDS]
          * (1.0 * (actions == logged_actions)).values
          / df[SampleBatch.REWARDS].mean()
      )
  
      if is_wis:
          se = float(
              np.std(ips_gain_vec / avg_ips_weight)
              / np.sqrt(len(ips_gain_vec / avg_ips_weight))
          )
      else:
          se = float(np.std(ips_gain_vec) / np.sqrt(len(ips_gain_vec)))
  
      return gain, se
  
imports: from typing import TYPE_CHECKING, Tuple
  import copy
  import gymnasium
  import numpy
  import os
  import shutil
  import tempfile
  import pandas
  from pathlib import Path
  import unittest
  import ray
  from ray.data import read_json
  from ray.rllib.algorithms.algorithm import Algorithm
  from ray.rllib.algorithms.dqn import DQNConfig
  from ray.rllib.examples.env.cliff_walking_wall_env import CliffWalkingWallEnv
  from ray.rllib.examples.policy.cliff_walking_wall_policy import CliffWalkingWallPolicy
  from ray.rllib.offline.dataset_reader import DatasetReader
  from ray.rllib.offline.estimators import DirectMethod, DoublyRobust, ImportanceSampling, WeightedImportanceSampling
  from ray.rllib.offline.estimators.fqe_torch_model import FQETorchModel
  from ray.rllib.policy.sample_batch import SampleBatch, concat_samples
  from ray.rllib.utils.framework import try_import_torch
  from ray.rllib.utils.numpy import convert_to_numpy
  from ray.rllib.utils.test_utils import check
label_desc: Use image node_id 1 for calling a global function with example usage: compute_expected_is_or_wis_estimator(df, policy, num_actions, is_wis) and returns: gain,  se