Source code for featuretools.entityset.relationship

[docs]class Relationship(object): """Class to represent an relationship between entities See Also: :class:`.EntitySet`, :class:`.Entity`, :class:`.Variable` """
[docs] def __init__(self, parent_variable, child_variable): """ Create a relationship Args: parent_variable (:class:`.Discrete`): Instance of variable in parent entity. Must be a Discrete Variable child_variable (:class:`.Discrete`): Instance of variable in child entity. Must be a Discrete Variable """ self.entityset = child_variable.entityset self._parent_entity_id = parent_variable.entity.id self._child_entity_id = child_variable.entity.id self._parent_variable_id = parent_variable.id self._child_variable_id = child_variable.id if (parent_variable.entity.index is not None and parent_variable.id != parent_variable.entity.index): raise AttributeError("Parent variable '%s' is not the index of entity %s" % (parent_variable, parent_variable.entity))
@classmethod def from_dictionary(cls, arguments, es): parent_entity = es[arguments['parent_entity_id']] child_entity = es[arguments['child_entity_id']] parent_variable = parent_entity[arguments['parent_variable_id']] child_variable = child_entity[arguments['child_variable_id']] return cls(parent_variable, child_variable) def __repr__(self): ret = u"<Relationship: %s.%s -> %s.%s>" % \ (self._child_entity_id, self._child_variable_id, self._parent_entity_id, self._parent_variable_id) return ret def __eq__(self, other): if not isinstance(other, self.__class__): return False return self._parent_entity_id == other._parent_entity_id and \ self._child_entity_id == other._child_entity_id and \ self._parent_variable_id == other._parent_variable_id and \ self._child_variable_id == other._child_variable_id def __hash__(self): return hash((self._parent_entity_id, self._child_entity_id, self._parent_variable_id, self._child_variable_id)) @property def parent_entity(self): """Parent entity object""" return self.entityset[self._parent_entity_id] @property def child_entity(self): """Child entity object""" return self.entityset[self._child_entity_id] @property def parent_variable(self): """Instance of variable in parent entity""" return self.parent_entity[self._parent_variable_id] @property def child_variable(self): """Instance of variable in child entity""" return self.child_entity[self._child_variable_id] @property def parent_name(self): """The name of the parent, relative to the child.""" if self._is_unique(): return self._parent_entity_id else: return '%s[%s]' % (self._parent_entity_id, self._child_variable_id) @property def child_name(self): """The name of the child, relative to the parent.""" if self._is_unique(): return self._child_entity_id else: return '%s[%s]' % (self._child_entity_id, self._child_variable_id) def to_dictionary(self): return { 'parent_entity_id': self._parent_entity_id, 'child_entity_id': self._child_entity_id, 'parent_variable_id': self._parent_variable_id, 'child_variable_id': self._child_variable_id, } def _is_unique(self): """Is there any other relationship with same parent and child entities?""" es = self.child_entity.entityset relationships = es.get_forward_relationships(self._child_entity_id) n = len([r for r in relationships if r._parent_entity_id == self._parent_entity_id]) assert n > 0, 'This relationship is missing from the entityset' return n == 1
class RelationshipPath(object): def __init__(self, relationships_with_direction): self._relationships_with_direction = relationships_with_direction @property def name(self): relationship_names = [_direction_name(is_forward, r) for is_forward, r in self._relationships_with_direction] return '.'.join(relationship_names) def entities(self): if self: # Yield first entity. is_forward, relationship = self[0] if is_forward: yield relationship.child_entity.id else: yield relationship.parent_entity.id # Yield the entity pointed to by each relationship. for is_forward, relationship in self: if is_forward: yield relationship.parent_entity.id else: yield relationship.child_entity.id def __add__(self, other): return RelationshipPath(self._relationships_with_direction + other._relationships_with_direction) def __getitem__(self, index): return self._relationships_with_direction[index] def __iter__(self): for is_forward, relationship in self._relationships_with_direction: yield is_forward, relationship def __len__(self): return len(self._relationships_with_direction) def __eq__(self, other): return isinstance(other, RelationshipPath) and \ self._relationships_with_direction == other._relationships_with_direction def __ne__(self, other): return not self == other def __repr__(self): if self._relationships_with_direction: path = '%s.%s' % (next(self.entities()), self.name) else: path = '[]' return '<RelationshipPath %s>' % path def _direction_name(is_forward, relationship): if is_forward: return relationship.parent_name else: return relationship.child_name