如何基于DataFrame构建NetworkX二分图?技术实现咨询
Hey there, let's put together a complete solution to build your desired bipartite graph based on the DataFrame structure you described. I'll break this down step by step with code examples you can adapt directly.
1. First, Import Required Libraries
We'll use pandas to handle the DataFrame and networkx (a popular graph library) to construct and work with the bipartite graph. If you don't have these installed, run pip install pandas networkx matplotlib first (matplotlib is for optional visualization later).
import pandas as pd import networkx as nx import matplotlib.pyplot as plt
2. Define Your Vertex Sets
- Set X: This is straightforward since column A has unique values—we can just take all entries from column A.
- Set Y: We need all unique values across columns B through K. Using
stack()will flatten these columns into a single series, thenunique()gives us distinct Y vertices.
3. Construct the Directed Bipartite Graph
We'll use a directed graph (DiGraph) because your edges go from Y to X, not the other way around. We'll also tag each vertex with a bipartite attribute to keep track of which set they belong to (0 for X, 1 for Y).
Here's the full code, including a sample DataFrame to test with:
# Sample DataFrame (replace this with your actual df) data = { 'A': ['x1', 'x2', 'x3', 'x4'], 'B': ['y1', 'y2', 'y1', 'y3'], 'C': ['y2', 'y3', 'y3', 'y4'], 'D': ['y1', None, 'y2', 'y4'], # Including a null value to show handling # Add columns E through K here as needed } df = pd.DataFrame(data) # Initialize directed bipartite graph G = nx.DiGraph() # Add X set vertices (column A) x_vertices = df['A'].tolist() G.add_nodes_from(x_vertices, bipartite=0) # Add Y set vertices (unique values from B-K) y_vertices = df.loc[:, 'B':'K'].stack().dropna().unique().tolist() G.add_nodes_from(y_vertices, bipartite=1) # Add directed edges: Y → X for each row match for _, row in df.iterrows(): x_node = row['A'] # Get all non-null Y values from columns B-K in this row y_nodes_in_row = row.loc['B':'K'].dropna().tolist() for y_node in y_nodes_in_row: G.add_edge(y_node, x_node)
4. Verify the Graph
To make sure everything works as expected, you can print out the vertices and edges:
# Check X set vertices print("X Set Vertices:", [n for n, attrs in G.nodes(data=True) if attrs['bipartite'] == 0]) # Check Y set vertices print("Y Set Vertices:", [n for n, attrs in G.nodes(data=True) if attrs['bipartite'] == 1]) # Check all directed edges print("Directed Edges (Y → X):", list(G.edges()))
5. Visualize the Graph (Optional)
If you want to see the graph visually, we can use matplotlib to plot it with the two bipartite sets separated:
# Get positions for bipartite layout x_set = {n for n, attrs in G.nodes(data=True) if attrs['bipartite'] == 0} pos = nx.bipartite_layout(G, x_set) # Draw the graph nx.draw( G, pos, with_labels=True, node_color=['skyblue' if n in x_set else 'lightgreen' for n in G.nodes()], node_size=1800, font_size=12, edge_color='gray' ) plt.title("Directed Bipartite Graph (Y → X)") plt.show()
Notes to Keep in Mind
- Null Values: The code uses
dropna()to skip any empty entries in columns B-K—adjust this if you want to handle nulls differently. - Duplicate Edges: If a row has the same Y value in multiple columns (e.g., both B and C are y1), this code will add duplicate edges. If you want only one edge per Y-X pair, convert
y_nodes_in_rowto a set first:y_nodes_in_row = list(set(row.loc['B':'K'].dropna().tolist())).
内容的提问来源于stack exchange,提问作者Peter Lewis

