class_docstr: Compute treatment effect whenever the effect is fully mediated by
  another variable (front-door) or when there is an instrument available.
  
  Currently only supports a linear model for the effects.
  
  Supports additional parameters as listed below.
class_docstr_tok: ["Compute","treatment","effect","whenever","the","effect","is","fully","mediated","by","another","variable","(","front-door",")","or","when","there","is","an","instrument","available",".","Currently","only","supports","a","linear","model","for","the","effects",".","Supports","additional","parameters","as","listed","below","."]
code: def build_first_stage_features(self, data_df: pd.DataFrame):
      treatment_vals = data_df[self._target_estimand.treatment_variable]
      if len(self._observed_common_causes_names) > 0:
          observed_common_causes_vals = data_df[
              self._observed_common_causes_names
          ]
          observed_common_causes_vals = pd.get_dummies(
              observed_common_causes_vals, drop_first=True
          )
      if self._effect_modifier_names:
          effect_modifiers_vals = data_df[self._effect_modifier_names]
          effect_modifiers_vals = pd.get_dummies(
              effect_modifiers_vals, drop_first=True
          )
      if type(treatment_vals) is not np.ndarray:
          treatment_vals = treatment_vals.to_numpy()
      if treatment_vals.shape[0] != data_df.shape[0]:
          raise ValueError(
              "Provided treatment values and dataframe should have the same length."
          )
      # Bulding the feature matrix
      n_samples = treatment_vals.shape[0]
      self.logger.debug(
          "Number of samples"
          + str(n_samples)
          + str(len(self._target_estimand.treatment_variable))
      )
      treatment_2d = treatment_vals.reshape(
          (n_samples, len(self._target_estimand.treatment_variable))
      )
      if len(self._observed_common_causes_names) > 0:
          features = np.concatenate(
              (treatment_2d, observed_common_causes_vals), axis=1
          )
      else:
          features = treatment_2d
      if self._effect_modifier_names:
          for i in range(treatment_2d.shape[1]):
              curr_treatment = treatment_2d[:, i]
              new_features = (
                  curr_treatment[:, np.newaxis]
                  * effect_modifiers_vals.to_numpy()
              )
              features = np.concatenate(
                  (features, new_features), axis=1
              )
      features = features.astype(
          float, copy=False
      )  # converting to float in case of binary treatment and no other variables
      # features = sm.add_constant(features, has_constant='add') # to add an intercept term
      return features
  
file_path: dowhy/dowhy/causal_estimators/two_stage_regression_estimator.py
imports: import copy
  from typing import Any, List, Optional, Type, Union
  import numpy
  import pandas
  from dowhy.causal_estimator import CausalEstimate, CausalEstimator
  from dowhy.causal_estimators.linear_regression_estimator import LinearRegressionEstimator
  from dowhy.causal_identifier import EstimandType, IdentifiedEstimand
  from dowhy.utils.api import parse_state
label_desc: Use image node_id 4 for calling the TwoStageRegressionEstimator obj's underlying member method code with example usage: obj.build_first_stage_features(data_df) and returns: features