code: def expected_bar_values_2d(dates,
                             assets,
                             asset_info,
                             colname,
                             holes=None):
      
      if colname == 'volume':
          dtype = uint32
          missing = 0
      else:
          dtype = float64
          missing = float('nan')
  
      data = full((len(dates), len(assets)), missing, dtype=dtype)
      for j, asset in enumerate(assets):
          # Use missing values when asset_id is not contained in asset_info.
          if asset not in asset_info.index:
              continue
  
          start = asset_start(asset_info, asset)
          end = asset_end(asset_info, asset)
          for i, date in enumerate(dates):
              # No value expected for dates outside the asset's start/end
              # date.
              if not (start <= date <= end):
                  continue
  
              if holes is not None:
                  expected = expected_bar_value_with_holes(
                      asset,
                      date,
                      colname,
                      holes,
                      missing,
                  )
              else:
                  expected = expected_bar_value(asset, date, colname)
  
              data[i, j] = expected
      return data
docs: Return an 2D array containing cls.expected_value(asset_id, date,
      colname) for each date/asset pair in the inputs.
  
      Missing locs are filled with 0 for volume and NaN for price columns:
  
          - Values before/after an asset's lifetime.
          - Values for asset_ids not contained in asset_info.
          - Locs defined in `holes`.