code: def compute_asset_lifetimes(frames):
      """
      Parameters
      ----------
      frames : dict[str, pd.DataFrame]
          A dict mapping each OHLCV field to a dataframe with a row for
          each date and a column for each sid, as passed to write().
  
      Returns
      -------
      start_date_ixs : np.array[int64]
          The index of the first date with non-nan values, for each sid.
      end_date_ixs : np.array[int64]
          The index of the last date with non-nan values, for each sid.
      """
      # Build a 2D array (dates x sids), where an entry is True if all
      # fields are nan for the given day and sid.
      is_null_matrix = np.logical_and.reduce(
          [frames[field].isnull().values for field in FIELDS],
      )
      if not is_null_matrix.size:
          empty = np.array([], dtype="int64")
          return empty, empty.copy()
  
      # Offset of the first null from the start of the input.
      start_date_ixs = is_null_matrix.argmin(axis=0)
      # Offset of the last null from the **end** of the input.
      end_offsets = is_null_matrix[::-1].argmin(axis=0)
      # Offset of the last null from the start of the input
      end_date_ixs = is_null_matrix.shape[0] - end_offsets - 1
  
      return start_date_ixs, end_date_ixs
  
imports: from functools import partial
  import h5py
  import logbook
  import numpy
  import pandas
  from six import iteritems, raise_from, viewkeys
  from six.moves import reduce
  from zipline.data.bar_reader import NoDataAfterDate, NoDataBeforeDate, NoDataForSid, NoDataOnDate
  from zipline.data.session_bars import CurrencyAwareSessionBarReader
  from zipline.utils.memoize import lazyval
  from zipline.utils.numpy_utils import bytes_array_to_native_str_object_array
  from zipline.utils.pandas_utils import check_indexes_all_same
label_desc: Use image node_id 3 for calling a global function with example usage: compute_asset_lifetimes(frames) and returns: start_date_ixs,  end_date_ixs, empty,  empty