Home > Blockchain >  Python numpy - string representation of a matrix to 2D numpy array while keeping formatting and feed
Python numpy - string representation of a matrix to 2D numpy array while keeping formatting and feed

Time:08-31

I need some help with my code. I have txt files in the following format (2 samples):

wwwwwwwwwwwwwwwwwwwwwwwwww
w...o.xx.o......o..xoxx..w
w...oooooo........o..o...w
w....xxx.........o.oxoo.ow
wx...............oxo...oow
wwwwwwwwww........o...wxxw
wb ...co..............wxxw
w  ........Ao....o....wxxw
wooo............. ....w..w
w......x....wwwwx x.oow..w
wc  .....x..ooxxo ....w..w
w   ..E..........b     ..w
wwwwwwwwwwwwwwwwwwwwwwwwww

and

wwwwwwwwwwwww
w........w..w
w...1.......w
w...A.1.w.0ww
www.w1..wwwww
w.......w.0.w
w.1........ww
w..........ww
wwwwwwwwwwwww

What I want to do is read all the files in the folder (there's maybe about 10 of these txt files), change all chars to 0 except for the character "w" and "A", these will be 1 and 2.

I managed to figure this part out, here's my partial solution:

import glob
import os
import re
import numpy as np
import ast
import networkx as nx
def create_matrix_from_layout(folder):
    files = glob.glob(folder)
    file_set = {}
    for f in files:
        fname = os.path.basename(f)
        with open(f, "r") as tmp:
            tmp_data = tmp.read()
        tmp_data = re.sub(r"[^wA\n]", r"0", tmp_data)
        tmp_data = tmp_data.replace("w", "1").replace("A", "2")
        arr = np.array(tmp_data)
        #print(arr.ndim)
        print(arr)
        #G = nx.from_numpy_matrix(arr)
        #print(G)

create_matrix_from_layout("layouts/*.txt")

Here's the output (sample):

111111111111111111111111
111100001000110000000111
100000101000000011000011
100000000011002011100001
101111011111000011000111
100000000100000000000011
110001000000110001110001
110000110001111000010001
111000000000000001000001
111111000000111111000011

All looks well, but here is where the problem begins. I need to feed it to NetworkX and create a graph that would consist of vertices (of 1s) and edges connecting them.

Obviously, my data structure is not something NetworkX wants to work with, but I haven't been able to figure out a way to do it better.

NetworkXError: Input array must be 2D, not 0

Any help would be appreciated! Thank you.

CodePudding user response:

You can create a grid graph, and then remove all nodes where you have a zero. In this way you will have a graph in which there is a node for each '1' in your matrix, and adjacent 1s are connected.

from itertools import product

import networkx as nx
import numpy as np

coor = np.array(list(product(*map(range, arr.shape))))
G = nx.grid_2d_graph(*arr.shape)
G.remove_nodes_from(map(tuple, coor[arr.flatten() == 0]))

Here the assumption is that arr is a numpy array containing 1 or 0. Here is an example:

>>> arr
array([[1, 1, 1, 1, 1],
       [1, 0, 0, 1, 0],
       [0, 0, 1, 1, 1],
       [1, 1, 1, 1, 1]])
>>> coor = np.array(list(product(*map(range, arr.shape))))
>>> G = nx.grid_2d_graph(*arr.shape)
>>> G.remove_nodes_from(map(tuple, coor[arr.flatten() == 0]))
>>> G.nodes
NodeView(((0, 0), (0, 1), (0, 2), (0, 3), (0, 4),
          (1, 0), (1, 3), (2, 2), (2, 3), (2, 4),
          (3, 0), (3, 1), (3, 2), (3, 3), (3, 4)))
>>> G.edges
EdgeView([((0, 0), (1, 0)), ((0, 0), (0, 1)), ((0, 1), (0, 2)),
          ((0, 2), (0, 3)), ((0, 3), (1, 3)), ((0, 3), (0, 4)),
          ((1, 3), (2, 3)), ((2, 2), (3, 2)), ((2, 2), (2, 3)),
          ((2, 3), (3, 3)), ((2, 3), (2, 4)), ((2, 4), (3, 4)),
          ((3, 0), (3, 1)), ((3, 1), (3, 2)), ((3, 2), (3, 3)),
          ((3, 3), (3, 4))])
  • Related