Exemplo n.º 1
0
    def neighbors_at(self, u=None, t=None, direction='out'):
        if not bool(self):
            if u is None:
                return NodeCollection()
            if t is None:
                return TimeCollection()
            return NodeSetS()

        mf = (self.df_.merge_function if self.weighted else None)
        if u is None:
            if t is None:
                out = dict()
                for u, val in self._build_time_generator(
                        set,
                        set_unweighted_n_sparse,
                        weighted=False,
                        direction=direction,
                        get_key=get_key_first,
                        sparse=True):
                    d = out.get(u, None)
                    if d is None:
                        out[u] = TimeSparseCollection([val],
                                                      discrete=self.discrete,
                                                      caster=NodeSetS)
                    else:
                        d.append(val)

                return NodeCollection(out)
            else:
                return LinkSetDF(self.df.df_at(t)[['u', 'v'] + self._wc],
                                 merge_function=mf,
                                 no_duplicates=False).neighbors_of(
                                     u=None, direction=direction)
        else:
            if direction == 'out':
                df = self.df[self.df.u == u].drop(
                    columns=['u'] + self._wc,
                    merge=False).rename(columns={'v': 'u'})
            elif direction == 'in':
                df = self.df[self.df.v == u].drop(columns=['v'] + self._wc,
                                                  merge=False)
            elif direction == 'both':
                df = self.df[self.df.u == u].drop(
                    columns=['u'] + self._wc).rename(columns={'v': 'u'})
                df = df.append(self.df[self.df.v == u].drop(columns=['v'] +
                                                            self._wc,
                                                            merge=True),
                               ignore_index=True)
            else:
                raise UnrecognizedDirection()
            if t is None:
                return TemporalNodeSetDF(df).nodes_at(t=None)
            else:
                return NodeSetS(df[df.index_at(t)].u.values.flat)
Exemplo n.º 2
0
 def common_time(self, u=None):
     if self.discrete:
         return self._common_time_discrete(u)
     else:
         if u is None:
             from stream_graph.collections import NodeCollection
             return NodeCollection({u: 0 for u in self.nodeset})
         elif self._common_time__list_input(u):
             from stream_graph.collections import NodeCollection
             return NodeCollection({v: 0 for v in u})
         return 0
Exemplo n.º 3
0
 def common_time_pair(self, l=None):
     if self.discrete:
         return self._common_time_pair_discrete(l)
     else:
         if l is None:
             from stream_graph.collections import NodeCollection
             return NodeCollection(
                 {l: 0
                  for l in combinations(self.nodeset, 2)})
         if self._common_time_pair__list_input(l):
             from stream_graph.collections import NodeCollection
             return NodeCollection({l: 0 for u in l})
         return 0
Exemplo n.º 4
0
    def common_time(self, u=None):
        if u is None:
            return NodeCollection(
                {u: (self.n - 1) * self.total_time
                 for u in self.nodeset_})
        elif isinstance(u, Iterable):
            return NodeCollection({
                u: (self.n - 1) * self.total_time
                for u in set(self.nodeset_) & set(u)
            })

        if bool(self) and u in self.nodeset_:
            return (self.n - 1) * self.total_time
        return 0.
Exemplo n.º 5
0
 def ego_betweeness(self, u=None, t=None, direction='both', detailed=False):
     df = self.sort_df('ts')
     both = direction == 'both'
     df = (df.rename(columns={'u': 'v', 'v': 'u'}) if direction == 'in' else df)
     lines = list(key for key in df[['u', 'v', 'ts']].itertuples(index=False, name=None))
     if u is None:
         neigh = {u: n.nodes_ for u, n in self.linkset.neighbors_of(direction=direction)}
         if t is None:
             return NodeCollection({u: functions.ego(u, neigh.get(u, set()), lines, both, detailed, self.discrete) for u in self.nodeset})
         else:
             return NodeCollection({u: functions.ego_at(u, neigh.get(u, set()), lines, t, both, detailed, self.discrete) for u in self.nodeset})
     elif t is None:
         return functions.ego(u, self.linkset.neighbors_of(u, direction=direction).nodes_, lines, both, detailed, self.discrete)
     else:
         return functions.ego_at(u, self.linkset.neighbors_of(u, direction=direction).nodes_, lines, t, both, detailed, self.discrete)
Exemplo n.º 6
0
    def degree_of(self, u=None, direction='out', weights=False):
        """Return the time-degree of a node at a certain time.

        Parameters
        ----------
        u : Node_Id

        direction : string={'in', 'out', 'both'}, default='both'

        weights : bool, default=False

        Returns
        -------
        degree : Number or LinkCollection
            Return the ('in', 'out' or 'both') time-degree of a node.
            If u is None return the degree for all node at time t.

        """
        if self.discrete:
            if self.weighted and weights:
                return self._degree_of_discrete_weights(u=u,
                                                        direction=direction)
            else:
                return self._degree_of_discrete(u=u, direction=direction)
        else:
            if u is None:
                from stream_graph.collections import NodeCollection
                return NodeCollection({u: 0. for u in self.nodeset})
            else:
                return .0
Exemplo n.º 7
0
 def _degree_of_discrete_weighted(self, u, direction):
     if u is None:
         out = Counter()
         if direction == 'out':
             for u, v, ts, w in self.df.itertuples(weights=True):
                 out[u] += w
         elif direction == 'in':
             for u, v, ts, w in self.df.itertuples(weights=True):
                 out[v] += w
         elif direction == 'both':
             for u, v, ts, w in self.df.itertuples(weights=True):
                 out[u] += w
                 out[v] += w
         else:
             raise UnrecognizedDirection()
         return NodeCollection(Counter(out))
     else:
         if direction == 'out':
             df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
         elif direction == 'in':
             df = self.df[self.df.v == u].drop(columns=['v'], merge=False)
         elif direction == 'both':
             df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
             df = df.append(self.df[self.df.v == u].drop(columns=['v'], merge=False), ignore_index=True, merge=True)
         else:
             raise UnrecognizedDirection()
         return df.w.sum()
Exemplo n.º 8
0
    def _degree_unweighted(self, u=None, direction='out'):
        if u is None:
            # Initialize iterators
            if direction == 'out':
                iter_ = (k[0] for k in self)
            elif direction == 'in':
                iter_ = (k[1] for k in self)
            elif direction == 'both':
                # Avoid double occurencies for degree i.e. (2, 1), (1, 2)
                iter_ = (a[0] for a in set(ks for k in self
                                           for ks in [k[:2], (k[1], k[0])]))
            else:
                raise UnrecognizedDirection()

            # Count how many times each node appears, as an indicator of how many neighbors it has.
            return NodeCollection(Counter(iter_))
        else:
            if direction == 'out':
                return (self.df.u == u).sum()
            elif direction == 'in':
                return (self.df.v == u).sum()
            elif direction == 'both':
                # Avoid double occurencies for degree i.e. (2, 1), (1, 2)
                return len(
                    set(
                        itertools.chain(self.df[self.df.u == u].v,
                                        self.df[self.df.v == u].u)))
            else:
                raise UnrecognizedDirection()
Exemplo n.º 9
0
    def _degree_weighted(self, u=None, direction='out'):
        if u is None:
            # Use a Counter to count the total weight sum.
            degrees = Counter()
            if direction == 'out':

                def add(key):
                    degrees[key[0]] += key[2]
            elif direction == 'in':

                def add(key):
                    degrees[key[1]] += key[2]
            elif direction == 'both':
                # Double occorencies do not matter here
                def add(key):
                    degrees[key[0]] += key[2]
                    degrees[key[1]] += key[2]
            else:
                raise UnrecognizedDirection()
            for key in iter(self):
                add(key)
            return NodeCollection(degrees)
        else:
            # Cast funciton to return the appropriate weigth series.
            def cast(index):
                return self.df.w[index]

            if direction == 'out':
                return cast(self.df.u == u).sum()
            elif direction == 'in':
                return cast(self.df.v == u).sum()
            elif direction == 'both':
                return cast((self.df.u == u) | (self.df.v == u)).sum()
            else:
                raise UnrecognizedDirection()
Exemplo n.º 10
0
 def times_of(self, u=None):
     if u is None:
         return NodeCollection({u: self.timeset for u in self.nodeset_})
     if bool(self) and u in self.timeset_:
         return self.timeset
     else:
         return TimeSetDF()
Exemplo n.º 11
0
    def neighbor_coverage_of(self, u=None, direction='out', weights=False):
        """Extract the neighbor coverage of the graph.

        Parameters
        ----------
        u: NodeId or None

        direction: 'in', 'out' or 'both', default='out'

        weights: Bool

        Returns
        -------
        total_coverage: Real or NodeCollection
            If u is Real, returns :math:`\\frac{d_{direction}(u)}{n^{2}}`.
            Otherwise returns the coverage of each node.

        """
        if bool(self):
            denom = float(self.n**2)
            if u is None:

                def fun(x, y):
                    return y / denom

                return self.linkset_.degree(direction=direction,
                                            weights=weights).map(fun)
            else:
                return self.linkset_.degree(
                    u, direction=direction, weights=weights) / denom
        else:
            if u is None:
                return NodeCollection()
            else:
                return 0.
Exemplo n.º 12
0
 def _duration_of_discrete(self, u=None):
     if u is None:
         return NodeCollection(Counter(u for u in self.df.u))
     else:
         if bool(self):
             return (self.df.u == u).sum()
         else:
             return 0
Exemplo n.º 13
0
 def duration_of(self, u=None):
     if self.discrete:
         return self._duration_of_discrete(u)
     else:
         if u is None:
             from stream_graph.collections import NodeCollection
             return NodeCollection({u: 0 for u in self.nodeset})
         return 0
Exemplo n.º 14
0
 def duration_of(self, u=None):
     if u is None:
         return NodeCollection({u: self.total_time for u in self.nodeset_})
     else:
         if u in self.nodeset_:
             return self.total_time
         else:
             return 0.
Exemplo n.º 15
0
 def _degree_of_unweighted(self, u, direction):
     if u is None:
         from stream_graph.collections import NodeCollection
         return NodeCollection({
             n: tns.size
             for n, tns in self.neighbors_of(None, direction=direction)
         })
     else:
         return self.neighbors_of(u, direction=direction).size
Exemplo n.º 16
0
 def times_of(self, u=None):
     if bool(self):
         if u is None:
             times = defaultdict(set)
             for u, ts in iter(self):
                 times[u].add(ts)
             # Make a time-set for each node
             return NodeCollection({
                 u: ITimeSetS(s, discrete=self.discrete)
                 for u, s in iteritems(times)
             })
         else:
             return ITimeSetS(self.df[self.df.u == u]['ts'].values.flat,
                              discrete=self.discrete)
     else:
         if u is None:
             return ITimeSetS()
         else:
             return NodeCollection(dict())
Exemplo n.º 17
0
    def neighbors_of(self, u=None, direction='out'):
        if not bool(self):
            if u is None:
                return dict()
            else:
                return TemporalNodeSetDF()
        if u is None:
            neighbors = defaultdict(list)
            if direction == 'out':

                def add(key):
                    neighbors[key[0]].append(key[1:])
            elif direction == 'in':

                def add(key):
                    neighbors[key[1]].append((key[0], ) + key[2:])
            elif direction == 'both':

                def add(key):
                    neighbors[key[0]].append(key[1:])
                    neighbors[key[1]].append((key[0], ) + key[2:])
            else:
                raise UnrecognizedDirection()
            for key in itertuples_raw(self.df,
                                      discrete=self.discrete,
                                      weighted=False):
                add(key)
            return NodeCollection({
                u: TemporalNodeSetDF(
                    init_interval_df(data=ns,
                                     discrete=self.discrete,
                                     weighted=False,
                                     disjoint_intervals=False,
                                     keys=['u']))
                for u, ns in iteritems(neighbors)
            })
        else:
            if direction == 'out':
                df = self.df[self.df.u == u].drop(
                    columns=['u'], merge=False).rename(columns={'v': 'u'})
            elif direction == 'in':
                df = self.df[self.df.v == u].drop(columns=['v'], merge=False)
            elif direction == 'both':
                df = self.df[self.df.u == u].drop(
                    columns=['u'], merge=False).rename(columns={'v': 'u'})
                df = df.append(self.df[self.df.v == u].drop(columns=['v'],
                                                            merge=False),
                               ignore_index=True,
                               merge=False)
            else:
                raise UnrecognizedDirection()
            if self.weighted:
                df = df.drop(columns='w', merge=False)
            return TemporalNodeSetDF(df, disjoint_intervals=False)
Exemplo n.º 18
0
 def times_of(self, u=None):
     if u is None:
         if bool(self):
             times = defaultdict(list)
             for key in itertuples_raw(self.df, discrete=self.discrete):
                 times[key[0]].append(key[1:])
             return NodeCollection({
                 u: TimeSetDF(init_interval_df(data=ts,
                                               discrete=self.discrete),
                              discrete=self.discrete,
                              disjoint_intervals=True)
                 for u, ts in iteritems(times)
             })
         else:
             return NodeCollection(dict())
     else:
         if bool(self):
             return TimeSetDF(self.df[self.df.u == u].drop(columns=['u'],
                                                           merge=True))
         else:
             return TimeSetDF()
Exemplo n.º 19
0
 def duration_of(self, u=None):
     if u is None:
         obj = defaultdict(float)
         dc = (1 if self.discrete else 0)
         for u, ts, tf in self.df.itertuples():
             obj[u] += tf - ts + dc
         return NodeCollection(obj)
     else:
         if bool(self):
             return self.df[self.df.u == u].measure_time()
         else:
             return 0
Exemplo n.º 20
0
    def degree_of(self, u=None, direction='out', weights=False):
        if not bool(self):
            if u is None:
                return dict()
            else:
                return TemporalNodeSetDF()

        if u is None:
            degree = Counter()
            dc = (1 if self.discrete else 0)
            if direction == 'out':

                def add(u, v, ts, tf, w=1):
                    degree[u] += (tf - ts + dc) * w
            elif direction == 'in':

                def add(u, v, ts, tf, w=1):
                    degree[v] += (tf - ts + dc) * w
            elif direction == 'both':

                def add(u, v, ts, tf, w=1):
                    degree[u] += (tf - ts + dc) * w
                    degree[v] += (tf - ts + dc) * w
            else:
                raise UnrecognizedDirection()

            kargs = ({'weights': True} if self.weighted and weights else {})
            for key in self.df.itertuples(**kargs):
                add(*key)

            return NodeCollection(degree)
        else:
            if direction == 'out':
                df = self.df[self.df.u == u].drop(columns=['u']).rename(
                    columns={'v': 'u'})
            elif direction == 'in':
                df = self.df[self.df.v == u].drop(columns=['v'])
            elif direction == 'both':
                df = self.df[self.df.u == u].drop(columns=['u']).rename(
                    columns={'v': 'u'})
                df = df.append(self.df[self.df.v == u].drop(columns=['v']),
                               ignore_index=True)
            else:
                raise UnrecognizedDirection()

            if self.weighted and weights:
                return df.w.sum()
            else:
                df = (df.drop(columns=['w'], merge=False)
                      if self.weighted else df)
                return TemporalNodeSetDF(df,
                                         disjoint_intervals=False,
                                         discrete=self.discrete).size
Exemplo n.º 21
0
    def common_time(self, u=None):
        if u is None or self._common_time__list_input(u):
            if not bool(self):
                return NodeCollection(dict())
            df = self.df.events
            active_nodes, common_times = set(), Counter()
            e = df.t.iloc[0]
            if u is None:

                def add_item(active_nodes, ct):
                    for v in (active_nodes):
                        common_times[v] += ct
            else:
                allowed_nodes = set(u)

                def add_item(active_nodes, ct):
                    for v in (active_nodes.intersection(allowed_nodes)):
                        common_times[v] += ct

            dc = (1 if self.discrete else 0)
            for u, t, f in df.itertuples(index=False, name=None):
                ct = (len(active_nodes) - 1) * (t - e + dc)
                if ct > .0:
                    add_item(active_nodes, ct)
                if f:
                    # start
                    active_nodes.add(u)
                else:
                    # finish
                    active_nodes.remove(u)
                e = t

            return NodeCollection(common_times)
        else:
            if bool(self):
                idx = (self.df.u == u)
                if idx.any():
                    a, b = self.df[idx], self.df[~idx]
                    return a.intersection_size(b)
            return 0.
Exemplo n.º 22
0
 def _common_time_discrete(self, u=None):
     if u is None or self._common_time__list_input(u):
         prev = None
         ct = defaultdict(int)
         if u is None:
             # If we want the common-time for all nodes
             for u, ts in self.sort_df('ts').itertuples():
                 if prev is None:
                     active_set, prev = {u}, ts
                 elif ts != prev:
                     if len(active_set) > 1:
                         for v in active_set:
                             # update their common time to the ammount of all the other coexisting nodes
                             ct[v] += (len(active_set) - 1)
                     active_set, prev = {u}, ts
                 else:
                     active_set.add(u)
             if len(active_set) > 1:
                 for v in active_set:
                     # update their common time to the ammount of all the other coexisting nodes
                     ct[v] += (len(active_set) - 1)
         else:
             # If we want the common-time for all nodes but only for a list of nodes
             valid_nodes = set(u)
             for u, ts in self.sort_df('ts').itertuples():
                 if prev is None:
                     active_set, prev = {u}, ts
                 elif ts != prev:
                     if len(active_set) > 1:
                         for v in active_set:
                             # update their common time to the ammount of all the other coexisting nodes
                             if v in valid_nodes:
                                 ct[v] += (len(active_set) - 1)
                     active_set, prev = {u}, ts
                 else:
                     active_set.add(u)
             if len(active_set) > 1:
                 for v in active_set:
                     # update their common time to the ammount of all the other coexisting nodes
                     if v in valid_nodes:
                         ct[v] += (len(active_set) - 1)
         return NodeCollection(ct)
     else:
         if bool(self):
             idx = (self.df.u == u)
             if idx.any():
                 a, b = self.df[idx], self.df[~idx]
                 # For a single node this is equivalent to the amount
                 # of intersection between two groups of time-sets
                 return a.intersection_size(b)
         return 0.
Exemplo n.º 23
0
 def _degree_at_weighted(self, u, t, direction):
     if u is None:
         if t is None:
             out = dict()
             for u, val in self._build_time_generator(
                     Counter,
                     sum_counter_n,
                     direction=direction,
                     get_key=get_key_first):
                 d = out.get(u, None)
                 if d is None:
                     out[u] = TimeCollection([val],
                                             discrete=self.discrete,
                                             instantaneous=False)
                 else:
                     d.append(val)
             return NodeCollection(out)
         else:
             return LinkSetDF(self.df.df_at(t)[['u', 'v', 'w']],
                              weighted=True,
                              merge_function=self.df_.merge_function,
                              no_duplicates=False).degree(
                                  u=None, direction=direction, weights=True)
     else:
         if direction == 'out':
             df = self.df[self.df.u == u].drop(
                 columns=['u'], merge=False).rename(columns={'v': 'u'})
         elif direction == 'in':
             df = self.df[self.df.v == u].drop(columns=['v'], merge=False)
         elif direction == 'both':
             df = self.df[self.df.u == u].drop(
                 columns=['u'], merge=False).rename(columns={'v': 'u'})
             df = df.append(self.df[self.df.v == u].drop(columns=['v'],
                                                         merge=True),
                            ignore_index=True)
         else:
             raise UnrecognizedDirection()
         if t is None:
             return TimeCollection(self._build_time_generator(
                 Counter, sum_counter_, direction=direction, df=df),
                                   discrete=self.discrete,
                                   instantaneous=False)
         else:
             return df.w[df.index_at(t)].sum()
Exemplo n.º 24
0
    def neighbors_of(self, u=None, direction='out'):
        if u is None:
            # A dictionary containing for its node it's set of neighbors
            neighbors = defaultdict(set)
            # Define a function for adding for its node it's neighbor.
            if direction == 'out':

                def add(u, v):
                    neighbors[u].add(v)
            elif direction == 'in':

                def add(u, v):
                    neighbors[v].add(u)
            elif direction == 'both':

                def add(u, v):
                    neighbors[u].add(v)
                    neighbors[v].add(u)
            else:
                raise UnrecognizedDirection()
            for key in iter(self):
                # Parse all elements.
                add(key[0], key[1])
            # Return a node-collection of nodesets.
            return NodeCollection(
                {u: NodeSetS(s)
                 for u, s in iteritems(neighbors)})
        else:
            # In case we want only one element
            if direction == 'out':
                # Extract the series of elements.
                s = self.df[self.df.u == u].v
            elif direction == 'in':
                s = self.df[self.df.v == u].u
            elif direction == 'both':
                s = itertools.chain(self.df[self.df.u == u].v,
                                    self.df[self.df.v == u].u)
            else:
                raise UnrecognizedDirection()
            # Return a Nodeset.
            return NodeSetS(s)
Exemplo n.º 25
0
    def duration_of(self, u=None):
        """Returns the duration of a node.

        Parameters
        ----------
        u : Node_Id or None

        Returns
        -------
        duration : Real or NodeCollection(Real)
            The total amount of time that a node exist.
            If None, returns a NodeCollection with the durations for all nodes in the temporal_nodeset.

        """
        if u is None:
            from stream_graph.collections import NodeCollection
            return NodeCollection(
                {u: self.times_of(u).size
                 for u in self.nodeset})
        else:
            return self.times_of(u).size
Exemplo n.º 26
0
 def _degree_at_unweighted(self, u, t, direction):
     if u is None:
         if t is None:
             out = dict()
             for u, val in self._build_time_generator(
                     set, len_set_n, direction=direction,
                     get_key=get_key_first):
                 d = out.get(u, None)
                 if d is None:
                     out[u] = TimeCollection([val],
                                             discrete=self.discrete,
                                             instantaneous=False)
                 else:
                     d.append(val)
             return NodeCollection(out)
         else:
             return LinkSetDF(self.df.df_at(t)[['u', 'v'] + self._wc],
                              no_duplicates=False).degree(
                                  u=None, direction=direction)
     else:
         df = (self.df.drop(columns='w', merge=False)
               if self.weighted else self.df)
         if direction == 'out':
             df = df[df.u == u].drop(
                 columns=['u'],
                 merge=self.weighted).rename(columns={'v': 'u'})
         elif direction == 'in':
             df = df[df.v == u].drop(columns=['v'], merge=self.weighted)
         elif direction == 'both':
             dfa = df[df.u == u].drop(
                 columns=['u'], merge=False).rename(columns={'v': 'u'})
             df = dfa.append(df[df.v == u].drop(columns=['v'], merge=False),
                             ignore_index=True,
                             merge=True)
         else:
             raise UnrecognizedDirection()
         if t is None:
             return TemporalNodeSetDF(df).n_at(t=None)
         else:
             return len(set(df.df_at(t).u.values.flat))
Exemplo n.º 27
0
 def _degree_of_discrete(self, u, direction):
     if u is None:
         if direction == 'out':
             iter_ = (u for u, v, ts in self.df.itertuples())
         elif direction == 'in':
             iter_ = (v for u, v, ts in self.df.itertuples())
         elif direction == 'both':
             # Avoid double occurencies
             iter_ = (u for u, _, _ in set(p for a, b, c in self.df.itertuples() for p in [(a, b, c), (b, a, c)]))
         else:
             raise UnrecognizedDirection()
         return NodeCollection(Counter(iter_))
     else:
         if direction == 'out':
             df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
         elif direction == 'in':
             df = self.df[self.df.v == u].drop(columns=['v'], merge=False)
         elif direction == 'both':
             df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
             df = df.append(self.df[self.df.v == u].drop(columns=['v'], merge=False), ignore_index=True, merge=True)
         else:
             raise UnrecognizedDirection()
         return ITemporalNodeSetDF(df, discrete=self.discrete).number_of_interactions
Exemplo n.º 28
0
    def neighbors_of(self, u=None, direction='out'):
        if not bool(self):
            if u is None:
                return {}
            else:
                return ITemporalNodeSetDF()

        if u is None:
            neighbors = defaultdict(set)
            if direction == 'out':
                def add(u, v, ts):
                    neighbors[u].add((v, ts))
            elif direction == 'in':
                def add(u, v, ts):
                    neighbors[v].add((u, ts))
            elif direction == 'both':
                def add(u, v, ts):
                    neighbors[u].add((v, ts))
                    neighbors[v].add((u, ts))
            else:
                raise UnrecognizedDirection()
            for u, v, ts in self.df.itertuples():
                # structure in neighboring relations for its node.
                add(u, v, ts)
            return NodeCollection({u: ITemporalNodeSetDF(ns) for u, ns in iteritems(neighbors)})
        else:
            if direction == 'out':
                df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
            elif direction == 'in':
                df = self.df[self.df.v == u].drop(columns=['v'], merge=False)
            elif direction == 'both':
                df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
                df = df.append(self.df[self.df.v == u].drop(columns=['v'], merge=False), ignore_index=True, merge=True)
            else:
                raise UnrecognizedDirection()
            return ITemporalNodeSetDF(df, no_duplicates=False, discrete=self.discrete)
Exemplo n.º 29
0
    def _degree_at_unweighted(self, u=None, t=None, direction='out'):
        if not bool(self):
            if u is None:
                return NodeCollection()
            if t is None:
                return TimeCollection(discrete=self.discrete, instantaneous=True)
            return 0

        if u is None:
            if t is None:
                out = dict()
                if direction == 'out':
                    def add(d, u, v):
                        d[u].add(v)
                elif direction == 'in':
                    def add(d, u, v):
                        d[v].add(u)
                elif direction == 'both':
                    def add(d, u, v):
                        d[u].add(v)
                        d[v].add(u)
                else:
                    raise UnrecognizedDirection()

                prev = None
                for u, v, ts in self.sort_df('ts').itertuples():
                    # Collect neighbors at each time-stamp
                    if prev is None:
                        cache = defaultdict(set)
                        prev = ts
                    elif ts != prev:
                        for z, s in iteritems(cache):
                            if z in out:
                                # and calculate their size
                                out[z].it.append((prev, len(s)))
                            else:
                                # in a TimeCollection of ascending time for each node
                                out[z] = TimeCollection([(prev, len(s))], discrete=self.discrete, instantaneous=True)
                        cache = defaultdict(set)
                        prev = ts
                    add(cache, u, v)
                # Add the remaining, from the cache
                for u, s in iteritems(cache):
                    if u in out:
                        out[u].it.append((prev, len(s)))
                    else:
                        out[u] = TimeCollection([(prev, len(s))], discrete=self.discrete, instantaneous=True)

                return NodeCollection(out)
            else:
                return LinkSetDF(self.df.df_at(t).drop(columns=['ts']), weighted=self.weighted).degree(u=None, direction=direction)
        else:
            if direction == 'out':
                df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
            elif direction == 'in':
                df = self.df[self.df.v == u].drop(columns=['v'], merge=False)
            elif direction == 'both':
                df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
                df = df.append(self.df[self.df.v == u].drop(columns=['v'], merge=False), ignore_index=True, merge=True)
            else:
                raise UnrecognizedDirection()
            if t is None:
                dt = defaultdict(set)
                # Collect all nodes for each time-stamp
                for u, ts in df.itertuples():
                    dt[ts].add(u)
                return TimeCollection(sorted(list((ts, len(us)) for ts, us in iteritems(dt))), discrete=self.discrete, instantaneous=True)
            else:
                return len(set(df.df_at(t).u.values.flat))
Exemplo n.º 30
0
    def _degree_at_weighted(self, u, t, direction):
        if u is None:
            if t is None:
                out = dict()
                if direction == 'out':
                    def add(d, u, v, w):
                        d[u] += w
                elif direction == 'in':
                    def add(d, u, v, w):
                        d[v] += w
                elif direction == 'both':
                    def add(d, u, v, w):
                        d[u] += w
                        d[v] += w
                else:
                    raise UnrecognizedDirection()

                prev = None
                for u, v, ts, w in self.sort_df('ts').itertuples(weights=True):
                    # Iterate in ascending time
                    if prev is None:
                        # For each node add all the weights for all its neighbors
                        cache = Counter()
                        prev = ts
                    elif ts != prev:
                        for z, weight in iteritems(cache):
                            if z in out:
                                # Append in ascending time inside the TimeCollection
                                out[z].it.append((prev, weight))
                            else:
                                # Initialize inside the TimeCollection
                                out[z] = TimeCollection([(prev, weight)], discrete=self.discrete, instantaneous=True)
                        cache = Counter()
                        prev = ts
                    add(cache, u, v, w)

                # Remove the remaining.
                for u, weight in iteritems(cache):
                    if u in out:
                        out[u].it.append((prev, weight))
                    else:
                        out[u] = TimeCollection([(prev, weight)], discrete=self.discrete, instantaneous=True)

                return NodeCollection(out)
            else:
                return LinkSetDF(self.df.df_at(t).drop(columns=['ts']), weighted=self.weighted, merge_function=self.df_.merge_function).degree(u=None, direction=direction, weights=True)
        else:
            if direction == 'out':
                df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
            elif direction == 'in':
                df = self.df[self.df.v == u].drop(columns=['v'], merge=False)
            elif direction == 'both':
                df = self.df[self.df.u == u].drop(columns=['u'], merge=False).rename(columns={'v': 'u'})
                df = df.append(self.df[self.df.v == u].drop(columns=['v'], merge=False), ignore_index=True, merge=True)
            else:
                raise UnrecognizedDirection()
            if t is None:
                dt = Counter()
                for u, ts, w in df.itertuples(weights=True):
                    # collect all the weights for its time-stamp.
                    dt[ts] += w
                return TimeCollection(sorted(list(iteritems(dt))), discrete=self.discrete, instantaneous=True)
            else:
                return df.df_at(t).w.sum()