将文本格式矩阵转换为NumPy二维数组并导入NetworkX构建图的技术问题求助
Let's break down and fix your issue step by step:
1. Why the NetworkX Error Occurs
Your current code converts the entire processed string into a 1D numpy array (each character is a single element in a flat array), but nx.from_numpy_matrix expects a 2D array (either an adjacency matrix or a grid structure). That's exactly why you're seeing the "Input array must be 2D, not 0" error.
2. Fix the Array Conversion
First, we need to turn your processed text into a proper 2D numpy array—each line of the text becomes a row in the array, and each character gets converted to an integer.
3. Build the Graph Correctly
Instead of using nx.from_numpy_matrix directly (it's designed for adjacency matrices, not grid data), we'll iterate through the 2D grid manually:
- Treat every position with value
1(original "w") as a node (we'll use the (row, column) tuple as a unique node ID). - For each node, check its four adjacent positions (up, down, left, right). If an adjacent position also has value
1, add an undirected edge between the two nodes.
Corrected Code
import glob import os import numpy as np import networkx as nx def create_matrix_from_layout(folder): files = glob.glob(folder) file_graphs = {} # Store graphs for each processed file for f in files: fname = os.path.basename(f) with open(f, "r") as tmp: tmp_data = tmp.read() # Step 1: Replace characters per your requirements tmp_data = tmp_data.replace("w", "1").replace("A", "2") # Replace all other characters (except newlines) with 0 tmp_data = ''.join(['0' if c not in {'1','2','\n'} else c for c in tmp_data]) # Step 2: Convert to a 2D numpy array of integers # Split into lines, skip empty lines from trailing newlines lines = [line.strip() for line in tmp_data.split('\n') if line.strip()] # Convert each line to a list of integers, then to numpy array grid = np.array([[int(c) for c in line] for line in lines], dtype=int) print(f"Processed grid for {fname}:\n{grid}\n") # Step 3: Build the NetworkX graph G = nx.Graph() rows, cols = grid.shape # Iterate over every cell in the grid for i in range(rows): for j in range(cols): if grid[i][j] == 1: # Add the grid position as a node G.add_node((i,j)) # Check adjacent cells for valid connections # Up if i > 0 and grid[i-1][j] == 1: G.add_edge((i,j), (i-1,j)) # Down if i < rows - 1 and grid[i+1][j] == 1: G.add_edge((i,j), (i+1,j)) # Left if j > 0 and grid[i][j-1] == 1: G.add_edge((i,j), (i,j-1)) # Right if j < cols - 1 and grid[i][j+1] == 1: G.add_edge((i,j), (i,j+1)) file_graphs[fname] = G print(f"Graph for {fname} has {G.number_of_nodes()} nodes and {G.number_of_edges()} edges\n") return file_graphs # Run the function with your layout files graphs = create_matrix_from_layout("layouts/*.txt")
Key Modifications Explained
- 2D Array Conversion: We split the processed text into lines, convert each line to a list of integers, then build a 2D numpy array. This gives us the grid structure NetworkX can work with.
- Graph Construction: Manual iteration over the grid lets us precisely control which nodes and edges are added—only
1positions become nodes, and edges only connect adjacent1s. - Node Identification: Using (row, column) tuples as node IDs makes it easy to map graph nodes back to their original positions in the text layout.
Verification
To check the output, you can inspect any graph in the returned dictionary:
# Example: Inspect the first processed graph first_fname = next(iter(graphs.keys())) G = graphs[first_fname] print(nx.info(G))
This should resolve the 2D array error and build the exact graph you need.
内容的提问来源于stack exchange,提问作者Pehy

