Remove all nodes that has a particular attribute in networkx - python

I`m trying to remove all nodes within a Graph that has an specific attribute value.
I have seen this: python networkx remove nodes and edges with some condition
But in that case the degree is a property and not an attribute.
My graph has an attribute call "Line" which could have different values like: A, B, C.
So for example I want to remove all nodes with attribute "Line" equal to A

You can filter nodes in your graph with a subgraph view:
filter_node = lambda node: G.nodes[node]['Line'] == 'A'
filtered_nodes = list(nx.subgraph_view(G, filter_node=filter_node).nodes)
You can then remove these nodes from the graph:
G.remove_nodes_from(e)

Related

Giving nodes in an ox graph a color based on an attribute

I have an ox graph, called G_map, with a geo data frame for nodes associated, as the following code.
G_nodes = ox.graph_to_gdfs(G_map,edges=False)
One of the G_nodes attributes is called 'osmid' and it's the ID of the node in open street map, so every single node has a different 'osmid'. My goal here is to plot the G_map graph giving certain nodes different colors, depending on the node ID, e.g., 'osmid'. For instance, if a node has a certain ID i would like for it to be red. I think I will have to use the osmnx function but I don't know how to do it exactly,
osmnx.plot.get_node_colors_by_attr()
I have also tried this:
node_c = ['b' if ('osmid'==25620516 or 'osmid'==25620570) else 'r' for idx in G_nodes(keys=True)]
fig, ax = ox.plot_graph(G_map, node_color=node_c, node_edgecolor='w', node_size=30, node_zorder=3, edge_color=ec, edge_linewidth=3)
But i get an error saying:
TypeError: 'GeoDataFrame' object is not callable
If anyone could help me,
Thank you!
You should be able to simply iterate over the graph and use the attributes of the nodes directly, e.g.:
['b' if (data['osmid']==25620516 or data['osmid']==25620570) else 'r' for node, data in G_map.nodes(data=True)]

runtime error: dictionary changed size during iteration

I have a social network graph 'G'.
I'm trying to check that they keys of my graph are in the characteristics dataset as well.
I ran this command:
for node in G.nodes():
if node in caste1.keys():
pass
else:
G = G.remove_node(node)
It shows an error RuntimeError: dictionary changed size during iteration
The RuntimeError is self-explanatory. You're changing the size of an object you're iterating within the iteration. It messes up the looping.
What you can do is to first iterate across the nodes to get the ones you would like to remove, and store it in a separate variable. Then you can iterate with this variable to remove the nodes:
# Identify nodes for removal
nodes2remove = [node for node in G.nodes() if node not in caste1.keys()]
# Remove target-nodes
for node in nodes2remove:
G = G.remove_node(node)

How to rename a single node of a networkx graph?

I wanted to know how I can change a single node name of a node of a digraph. I am new to networkx and could only find answers on how to change all node names.
In my case I am iterating over a graph A to create graph B. p and c are nodes of graph A. The edge (p,c) of graph A contains data I want to add to the node p of B. However, when I am adding the edge data from graph A to the already existing node p of graph B, I would like to update the name of p to be equal to the name of c so I am able to reference it again for the next edge of graph A because it then is the edge (c,x) and I can use the c to reference it again...
The relevant part of my code looks like this
new_stages = A.in_edge(c, data='stages')
stages = B.node[p]['stages']
stages.append(new_stages)
<<Update node p to have name of c??>>
B.add_node(p, stages=new_stage_set)
Any help is appreciated, thanks!
You have nx.relabel_nodes for this. Here's a simple use case:
G = nx.from_edgelist([('a','b'), ('f','g')])
mapping = {'b':'c'}
G = nx.relabel_nodes(G, mapping)
G.edges()
# EdgeView([('a', 'c'), ('f', 'g')])

Networkx set complex node attribute

I want to individually update nodes for a certain new custom attribute called 'journeys', but am having severe difficulties with it.
Say I have some graph:
import pandas as pd
import networkx as nx
cols = ['node_a','node_b','travel_time','attribute']
data = [['A','B',3,'attribute1'],
['B','C',1,'attribute1'],
[ 'C','D',7,'attribute1'],
['D','E',3,'attribute1'],
['E','F',2,'attribute1'],
['F','G',4,'attribute1'],
['A','L',4,'attribute2'],
['L','D',3,'attribute2']
]
edges = pd.DataFrame(data)
edges.columns = cols
G=nx.convert_matrix.from_pandas_edgelist(edges,'node_a','node_b', ['travel_time','attribute'])
For each node, I want to add an attribute in the form of {direction: [[id,timestamp, set_of_carrying_items]]} where the inner one is a list of lists as i want to add more lists of the form [id,timestamp, carrying_items] to it.
Example: Update a particular node A with
new_attribute = {'A':{'up': [[0, Timestamp('1900-01-01 05:31:00'), set()]]}}}
However, no matter what I try, the node doesnt get updated correctly. nx.get_node_attributes(G, 'A') returns an empty dictionary. But nx.get_node_attributes(G,'up') returns the attribute!!
It seems i'm setting it wrongly but I cant figure out how. Anyone know the proper way?
Using networkx 2.4
Solved it.
nx.get_node_attributes(G,X) returns attributes called X for all nodes. You're looking for G.node['nodeA']
if your attribute is of the form {'nodeA':{'attribute_name': value}}, you'll set value to attribute_name for node nodeA.
For example, in my case:
att = {'nodeA':{'up': [[1, Timestamp('1900-01-01 22:31:00'), set()]]}}}
nx.set_node_attributes(G,att)
works

Recursively add Subgraphs to all Nodes in a Graph

So, I've a data structure of graph as follows:
graph = {'graphData': {'nodes': List of Nodes,
'edges': List of Edges,}
}
In addition to that, I've a list of subgraphs as follows:
In first step, I add those subgraphs having one node as SOI [3 under Annotation 3] together to form something like this:
The following code take care of it:
for coreferanceGraph in unattached_graphs:
coreferanceGraph = self.merge_entity_in_graph(soi_node, coreferanceGraph, "value-entityName")
if coreferanceGraph:
edges_in_coreferenceGraph = coreferanceGraph['graphData']['edges']
nodes_in_coreferenceGraph = coreferanceGraph['graphData']['nodes']
for node in nodes_in_coreferenceGraph:
if node not in graph['graphData']['nodes']:
graph['graphData']['nodes'].append(node)
for edge in edges_in_coreferenceGraph:
if edge not in graph['graphData']['edges']:
graph['graphData']['edges'].append(edge)
attached_graphs.append(coreferanceGraph)
else:
continue
What happens in above code is that:
For every unattached subgraph in 1st image, I find if any subgraph has SOI node using function merge_entity_in_graph(). If SOI is present in subgraph, the subgraph is returned, and added to original Graph variables of structure defined defined by variables graph = dict().
In next step, I want to recursively add all those sugraphs in Image 1, to be added to open nodes present. In my case, according to Image 2, thats Ec, Ep, E1.
What I expect is:
Had there been more subgraphs with one of their nodes as Ef, Eq, Er, they also would have been added recursively.
My question is, how do I achieve this? I've written a method as follows, but not sure weather approach is right or not:
def add_other_subgraphs(self, subgraph, node, all_nodes, graph, coreference_graphs):
"""
Args:
subgraph (dict):
node (dict):
all_nodes (list):
graph (dict):
Returns:
"""
subgraph_edges = subgraph['graphData']['edges']
subgraph_nodes = subgraph['graphData']['nodes']
for node in subgraph_nodes:
if node not in graph['graphData']['nodes']:
graph['graphData']['nodes'].append(node)
for edge in subgraph_edges:
if edge not in graph['graphData']['edges']:
graph['graphData']['edges'].append(edge)
for node in graph['graphData']['nodes']:
coreference_graph = self.fetch_coreference_graph(node, coreference_graphs)
if coreference_graph:
graph = self.add_other_subgraphs(coreference_graph, node, all_nodes, graph, coreference_graphs)
else:
return graph
return graph
And the function add_other_subgraphs() will be called for each of Nodes i.e. Ec, Ep, E1

Categories

Resources