class_docstr: An ExternalIdIndex maps between "external IDs" and "integer locations" or "internal locations"
  (ilocs).
  
  It is designed to allow handling only efficient integers internally, but easily convert between
  them and the user-facing IDs.
class_docstr_tok: ["An","ExternalIdIndex","maps","between","``","external","IDs","''","and","``","integer","locations","''","or","``","internal","locations","''","(","ilocs",")",".","It","is","designed","to","allow","handling","only","efficient","integers","internally",",","but","easily","convert","between","them","and","the","user-facing","IDs","."]
code: def __init__(self, ids):
      self._index = pd.Index(ids)
      # reserve 2 ^ (n-bits) - 1 for sentinel
      self.dtype = np.min_scalar_type(len(self._index))
  
      if not self._index.is_unique:
          # had some duplicated IDs, which is an error
          duplicated = self._index[self._index.duplicated()].unique()
          raise ValueError(
              f"expected IDs to appear once, found some that appeared more: {comma_sep(duplicated)}"
          )
  
imports: import itertools
  from collections import defaultdict
  import numpy
  import pandas
  import scipy.sparse
  from ..globalvar import SOURCE, TARGET, WEIGHT, TYPE_ATTR_NAME
  from .validation import require_dataframe_has_columns, comma_sep
label_desc: Use image node_id 1 to create a new ExternalIdIndex object  with example: obj = ExternalIdIndex(ids)