docstr: Update the :class:`~perspective.Table` with new data.
  
  Updates on :class:`~perspective.Table` without an explicit ``index``
  are treated as appends.  Updates on :class:`~perspective.Table` with
  an explicit ``index`` should have the index as part of the ``data``
  param, as this instructs the engine to locate the indexed row and write
  into it.  If an index is not provided, the update is treated as an
  append.
  
  Args:
      data (:obj:`dict`/:obj:`list`/:obj:`pandas.DataFrame`): The data
          with which to update the :class:`~perspective.Table`.
  
  Examples:
      >>> tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="a")
      >>> tbl.update({"a": [2, 3], "b": ["a", "a"]})
      >>> tbl.view().to_dict()
      {"a": [1, 2, 3], "b": ["a", "a", "a"]}
docstr_tok: ["Update","the",":","class",":","`","~perspective.Table","`","with","new","data",".","Updates","on",":","class",":","`","~perspective.Table","`","without","an","explicit","``","index","``","are","treated","as","appends",".","Updates","on",":","class",":","`","~perspective.Table","`","with","an","explicit","``","index","``","should","have","the","index","as","part","of","the","``","data","``","param",",","as","this","instructs","the","engine","to","locate","the","indexed","row","and","write","into","it",".","If","an","index","is","not","provided",",","the","update","is","treated","as","an","append",".","Args",":","data","(",":","obj",":","`","dict","`","\/",":","obj",":","`","list","`","\/",":","obj",":","`","pandas.DataFrame","`",")",":","The","data","with","which","to","update","the",":","class",":","`","~perspective.Table","`",".","Examples",":",">",">",">","tbl","=","Table","(","{","``","a","''",":","[","1",",","2",",","3","]",",","``","b","''",":","[","``","a","''",",","``","b","''",",","``","c","''","]","}",",","index=","''","a","''",")",">",">",">","tbl.update","(","{","``","a","''",":","[","2",",","3","]",",","``","b","''",":","[","``","a","''",",","``","a","''","]","}",")",">",">",">","tbl.view","(",")",".to_dict","(",")","{","``","a","''",":","[","1",",","2",",","3","]",",","``","b","''",":","[","``","a","''",",","``","a","''",",","``","a","''","]","}"]
code: def update(self, data, port_id=0):
      """Update the :class:`~perspective.Table` with new data.
  
      Updates on :class:`~perspective.Table` without an explicit ``index``
      are treated as appends.  Updates on :class:`~perspective.Table` with
      an explicit ``index`` should have the index as part of the ``data``
      param, as this instructs the engine to locate the indexed row and write
      into it.  If an index is not provided, the update is treated as an
      append.
  
      Args:
          data (:obj:`dict`/:obj:`list`/:obj:`pandas.DataFrame`): The data
              with which to update the :class:`~perspective.Table`.
  
      Examples:
          >>> tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="a")
          >>> tbl.update({"a": [2, 3], "b": ["a", "a"]})
          >>> tbl.view().to_dict()
          {"a": [1, 2, 3], "b": ["a", "a", "a"]}
      """
      if not port_id:
          port_id = 0
  
      _is_arrow = isinstance(data, (bytes, bytearray))
      _is_csv = isinstance(data, str)
  
      if _is_csv:
          # CSVs are loaded using the Arrow interface, so is_arrow is
          # always true if we are loading a CSV
          _is_arrow = True
  
          if len(data) > 0 and data[0] == ",":
              data = "_" + data
  
      if _is_arrow:
          _accessor = data
          self._table = update_table(
              self._table,
              _accessor,
              self._limit or 4294967295,
              self._index or "",
              t_op.OP_INSERT,
              _is_arrow,
              _is_csv,
              port_id,
          )
          self._state_manager.set_process(
              self._table.get_pool(), self._table.get_id()
          )
          return
  
      columns = self.columns()
      types = self._table.get_schema().types()
      _accessor = _PerspectiveAccessor(data)
      _accessor._names = columns + [
          name for name in _accessor._names if name == "__INDEX__"
      ]
      _accessor._types = types[: len(columns)]
  
      if _accessor._is_numpy:
          # Try to cast arrays to the Perspective dtype before they end up in
          # the C++, thus allowing for int/floats to be copied when they are
          # the same bit width
          _accessor.try_cast_numpy_arrays()
  
      if "__INDEX__" in _accessor._names:
          if self._index is not None:
              index_pos = _accessor._names.index(self._index)
              index_dtype = _accessor._types[index_pos]
              _accessor._types.append(index_dtype)
          else:
              _accessor._types.append(t_dtype.DTYPE_INT32)
  
      self._table = update_table(
          self._table,
          _accessor,
          self._limit or 4294967295,
          self._index or "",
          t_op.OP_INSERT,
          False,
          False,
          port_id,
      )
      self._state_manager.set_process(
          self._table.get_pool(), self._table.get_id()
      )
  
imports: from datetime import date, datetime
  from ..core.exception import PerspectiveError
  from ._accessor import _PerspectiveAccessor
  from ._callback_cache import _PerspectiveCallBackCache
  from ._date_validator import _PerspectiveDateValidator
  from ._state import _PerspectiveStateManager
  from ._utils import _dtype_to_pythontype, _dtype_to_str, _parse_expression_inputs, _str_to_pythontype
  from .libpsppy import make_table, update_table, str_to_filter_op, t_dtype, t_filter_op, t_op, validate_expressions
  from .view import View
label_desc: Use image node_id 16 for calling the Table obj's underlying member method code with example usage: obj.update(data, port_id) without return types