Exemple #1
0
    def __getitem__(self, key, key_id=None, key_var=None):
        """
        Returns a specific value by asking the table
        for the value.
        
        The numerical key_id or Variable key_var can be given explicitly.
        This prevents dictionary lookups below. Just 'key' is either a key_id
        or a key_var.
        
        TODO:
        - Pull from self.table instead of from self.table.widget_origin?
        """
        
        # Convert from 'key' to the numerical 'key_id'
        if key_id is None:
            if not isinstance(key, Integral):
                key_id = self._domain.index(key)
            else:
                key_id = key
        
        # Get key_var for the Variable itself.
        if key_var is None:
            key_var = self.table.domain[key_id]

        # Get the value cached in memory.
        #value = self._values[keyid]
        # ._value has been removed in Orange 3.2
        value = RowInstance.__getitem__(self, key=key, key_id=key_id, key_var=key_var)

        # A nan means the value is not yet available.
        if numpy.isnan(value):
            # Pull and cache the value.
            # TODO: Pull from self.table.widget_origin?
            if self.table.widget_origin is not None:
                value = self.table.widget_origin.pull_cell(self.row_index_full, key_var)
            elif self.table.table_origin is not None:
                value = self.table.table_origin[self.row_index_full][key_var]

            # TODO: Is this necessary? Where does the 'int' come from?
            if isinstance(value, (int, numpy.float)):
                value = float(value)

            # Cache the value both in this RowInstance as well as in
            # the original table.
            # TODO: Can we do everything with only self.table.X?
            #self._values[keyid] = value
            # ._values is removed in Orange 3.2
            RowInstance.__setitem__(self, key_var, value)

            # Only cache in self.table if there is a corresponding row there.
            # TODO: Should we do this caching here at all? Probably better
            #   to do this in the LazyTable itself? E.g. preventing this
            #   pylint warning:
            # pylint: disable=protected-access
            if self.row_index_materialized is not None:
                if 0 <= key_id < len(self._domain.attributes):
                    self.table.X[self.row_index_materialized][key_id] = value
                elif key_id >= len(self._domain.attributes):
                    self.table._Y[self.row_index_materialized][key_id - len(self.domain.attributes)] = value
                else:
                    self.table._metas = self._metas[-1 - key_id]

        val = Value(self._domain[key_id], value)

        return val
Exemple #2
0
    def __init__(self, table, row_index, region_of_interest_only=False):
        """
        Construct a data instance representing the given row of the table.
        row_index is the real row of the data set, which might not be the
        materialized row.

        When region_of_interest_only is set, then the row is only stored
        in the table if it's in the region_of_interest. It should only be
        necessary to set this flag internally.

        TODO:
        - Ensure that rows that are not in the region of interest are
          removed from memory because saving memory is the reason they are
          not appended to the table.
        - Perhaps cache whether an instance is in the region of interest
          so they can be skipped later.
        """

        # The table that this row belongs to, should be a LazyTable instance.
        self.table = table

        # row_index_full is enough to get the attribute values of this row.
        self.row_index_full = row_index

        # TODO: A None for row_index_materialized should not happen anymore
        #   because this is now checked in LazyTable.__getitem__(). However
        #   this does mean that the in_roi code is not functional anymore.
        #   Replace all the RoI code with Filters?
        # row_index_materialized is used to cache the attribute values in
        # memory in self.table.X, Y and metas. It is set to None if there is
        # no corresponding row in self.table.
        self.row_index_materialized = table.row_mapping.get(self.row_index_full, None)

        if self.row_index_materialized is None:
            # The row has not yet been stored in the table. We instantiate
            # Instance (super of RowInstance) instead of RowInstance because
            # there is no corresponding row in memory yet.
            # pylint: disable=non-parent-init-called
            Instance.__init__(self, table.domain)
            # Nevertheless, from this moment on, we can use this
            # LazyRowInstance because all attribute values can be retrieved
            # on the fly.
            if self.in_filters():
                # The row is new and within the filter.
                # Therefore needs to be added to be appended to self.table
                # if it is within the region_of_interest as well.
                self_in_region_of_interest = self.in_region_of_interest()
                if not region_of_interest_only or self_in_region_of_interest:
                    # TODO: Replace the region_of_interest with Filters.
                    # The new row_index_materialized
                    # will be set to the current length of the table in memory.
                    # This ensures that the row is inserted at the right place
                    # (that is, at the end) when appending.
                    self.row_index_materialized = table.len_instantiated_data()
                    self.row_index = self.row_index_materialized
                    self.table.append(self)
                    self.table.row_mapping[self.row_index_full] = self.row_index_materialized
                    # A full RowInstance can now be initialized because the row
                    # is indeed available in the table.
                    RowInstance.__init__(self, table, self.row_index_materialized)
                else:
                    # This new row is not available in the table, and we'd like
                    # to keep it this way to conserve memory.
                    self.row_index_materialized = None
                    self.row_index = self.row_index_materialized
            else:
                # This new row is not available in the table, and we'd like
                # to keep it this way to conserve memory.
                self.row_index_materialized = None
                self.row_index = self.row_index_materialized
        else:
            # The row is already available in the table.
            RowInstance.__init__(self, table, self.row_index_materialized)